asp.net-mvc – 如何使用Simple Injector装饰ASP.NET MVC控制器

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – 如何使用Simple Injector装饰ASP.NET MVC控制器前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想对我的MVC控制器应用一些横切关注点.目前,这是通过抽象基类实现的,但是当我们重构更多的代码库以利用依赖注入时,我想知道这是否是Simple Injector可以帮助我通过它的装饰或拦截设施.

所以我试图创建一个非常基本的装饰器:

public class ControllerDecorator : IController
{
    private readonly IController _controller;

    public ControllerDecorator(IController controller)
    {
        _controller = controller;
    }

    public void Execute(RequestContext requestContext)
    {
        // Do something of a cross-cutting nature here...

        _controller.Execute(requestContext);
    }
}

在我的作文根:container.RegisterDecorator< IController,ControllerDecorator>()

但是,我的装饰器的Execute方法中的代码似乎永远不会被调用.是因为MVC框架直接解析我的控制器类而不是通过IController吗?在那种情况下,我该怎么办?我在这里想念的是什么?

解决方法

在默认配置中,您无法将装饰器应用于控制器.原因是MVC的DefaultControllerFactory按其具体类型请求控制器.因为它请求具体类型,Simple Injector无法应用装饰器;它必须假设调用者需要这种具体类型,因此必须返回这种确切的类型(或子类型).

解决此问题,您必须使用自定义的DefaultControllerFactory替换默认的DefaultControllerFactory:

public class SimpleInjectorControllerFactory : DefaultControllerFactory {
    public IDictionary<Type,InstanceProducer> Producers { get; set; }
    protected override IController GetControllerInstance(RequestContext rc,Type type) {
        return (IController)this.Producers[type].GetInstance();
    }
}

接下来,在您的引导程序中,您必须使用以下内容替换对RegisterMvcControllers的调用

var controllerTypes = SimpleInjectorMvcExtensions.GetControllerTypesToRegister(
    container,Assembly.GetExecutingAssembly());

var controllerProducers = controllerTypes
    .ToDictionary(type => type,type => CreateControllerProducer(container,type));

// Verify after creating the controller producers.
container.Verify();

ControllerBuilder.Current.SetControllerFactory(
    new SimpleInjectorControllerFactory { Producers = controllerProducers });

CreateControllerProducer方法如下所示:

private static InstanceProducer CreateControllerProducer(Container c,Type type) {
    var producer = Lifestyle.Transient.CreateProducer(typeof(IController),type,c);
    producer.Registration.SuppressDiagnosticWarning(
        DiagnosticType.DisposableTransientComponent,"MVC disposes the controller when the web request ends.");
    return producer;
}

关键部分是对CreateProducer的调用提供了typeof(IController);这允许Simple Injector为IController应用装饰器.

就是这个;现在您可以为IController注册装饰器.

但是有一个警告:使用Web API和新的ASP.NET核心,不可能将装饰器应用于控制器.两个框架都期望具体类型;如果你包装真正的控制器它们会破裂.这些框架装饰控制器的首选方法是通过OWIN管道.所以这个答案仅适用于MVC 3,4和5.

原文链接:https://www.f2er.com/aspnet/248302.html

猜你在找的asp.Net相关文章