gpt4 book ai didi

asp.net-mvc - 如何使用简单注入(inject)器装饰 ASP.NET MVC Controller

转载 作者:行者123 更新时间:2023-12-02 05:42:51 26 4
gpt4 key购买 nike

我想对我的 MVC Controller 应用一些横切关注点。目前,这是通过抽象基类实现的,但是当我们重构更多的代码库以利用依赖注入(inject)时,我想知道 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框架直接解析我的 Controller 类而不是经过IController ?既然如此,我能做什么呢?我在这里缺少什么?

最佳答案

在默认配置中,您无法将装饰器应用于 Controller 。原因是 MVC 的 DefaultControllerFactory 通过 Controller 的具体类型来请求 Controller 。因为它需要具体类型,所以简单注入(inject)器无法应用装饰器;它必须假设调用者需要这个具体类型,因此必须返回这个确切的类型(或子类型)。

要解决此问题,您必须将默认的 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();
}
}

接下来,在 Bootstrap 中,您必须将 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) 提供的;这允许简单注入(inject)器为 IController 应用装饰器。

就是这样;现在您可以为 IController 注册您的装饰器。

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

关于asp.net-mvc - 如何使用简单注入(inject)器装饰 ASP.NET MVC Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32118849/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com