简体   繁体   English

使用Simple Injector和IHttpControllerActivator解决ASP.NET Web API中的依赖项

[英]Resolve dependencies in ASP.NET Web API with Simple Injector and IHttpControllerActivator

I am currently using Simple Injector to resolve dependencies into my Asp.Net Web Api projects. 我目前正在使用Simple Injector来解决对Asp.Net Web Api项目的依赖。

From the documentation you can configure it like that: 您可以从文档中进行如下配置:

protected void Application_Start() {
    // Create the container as usual.
    var container = new Container();
    container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

    // Register your types, for instance using the scoped lifestyle:
    container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Scoped);

    // This is an extension method from the integration package.
    container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

    container.Verify();

    GlobalConfiguration.Configuration.DependencyResolver =
        new SimpleInjectorWebApiDependencyResolver(container);

    // Here your usual Web API configuration stuff.
}

The main points here are to register the Web Api controllers and set a custom dependency resolver. 这里的要点是注册Web Api控制器并设置自定义依赖项解析器。

However I've just read these article from Mark Seemann on how to configure dependency injection in Asp.Net Web Api: 但是,我刚刚阅读了Mark Seemann的有关如何在Asp.Net Web Api中配置依赖项注入的文章:

From these articles, I've learnt that there is a better option than implementing IDependencyResolver to resolve Web Api dependencies. 从这些文章中,我了解到有比实现IDependencyResolver更好的选择来解决Web Api依赖关系。 This other option is to create an implementation of the IHttpControllerActivator that acts as an Adapter over the IoC Container. 另一种选择是创建IHttpControllerActivator的实现,该实现充当IoC容器上的适配器。

Here is the implementation I've coded using SimpleInjector: 这是我使用SimpleInjector编码的实现:

public class SimpleInjectorControllerActivator : IHttpControllerActivator
{
    private readonly Container _container;

    public SimpleInjectorControllerActivator(Container container)
    {
        _container = container;
    }

    public IHttpController Create(HttpRequestMessage request,
        HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        request.RegisterForDispose(_container.BeginExecutionContextScope());

        return (IHttpController)_container.GetInstance(controllerType);
    }
}

and in the Application_Start method, I've replaced this line: Application_Start方法中,我替换了以下行:

GlobalConfiguration.Configuration.DependencyResolver =
    new SimpleInjectorWebApiDependencyResolver(container);

by this line : 通过此行:

GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator),
    new SimpleInjectorControllerActivator(container));

I would like to know if the implementation of the IHttpControllerActivator is valid and also if this approach is valid and will work as good as the normal one ? 我想知道IHttpControllerActivator的实现是否有效,并且这种方法是否有效,是否会像普通方法一样有效?

Yes, your implementation is valid. 是的,您的实施有效。

Only be careful not to use both the SimpleInjectorWebApiDependencyResolver and the SimpleInjectorControllerActivator in the same application. 请注意不要在同一应用程序中同时使用SimpleInjectorWebApiDependencyResolverSimpleInjectorControllerActivator Both start an ExecutionContextScope which could lead to having two scopes within the same web request, so they are mutually exclusive. 两者都启动一个ExecutionContextScope ,这可能导致在同一Web请求中具有两个范围,因此它们是互斥的。

A general advantage of using a controller activator over the dependency resolver is that the dependency resolver contract forces the adapter to return null when a service can't be created. 与依赖解析器相比,使用控制器激活器的一般优势在于,依赖解析器协定强制适配器在无法创建服务时返回null This is a very common problem that developers run into, and it often causes the confusing controller does not have a default constructor exception. 这是开发人员遇到的一个非常常见的问题,它通常导致令人困惑的控制器没有默认的构造函数异常。 This problem does not exist when using an IHttpControllerActivator , since the contract forces you to return a value or throw an exception. 使用IHttpControllerActivator时不存在此问题,因为该合同会强制您返回值或引发异常。

The Simple Injector Web API integration project however, prevents this problem with dependency resolver, by never returning null (but throwing an exception instead) in case the requested service is an API controller (and thereby implicitly breaking the IDependencyResolver 's contract). 但是,Simple Injector Web API集成项目通过在请求的服务是API控制器的情况下从不返回null (而是抛出异常)(从而隐式打破IDependencyResolver的合同)来避免依赖项解析器出现此问题。

An advantage of using the SimpleInjectorDependencyResolver is that it becomes easier to create message handlers that operate within the execution context scope, since you can trigger the creation of this scope by calling request.GetDependencyScope() method. 使用SimpleInjectorDependencyResolver一个优点是,创建在执行上下文范围内运行的消息处理程序变得更加容易,因为您可以通过调用request.GetDependencyScope()方法来触发此范围的创建。 With the current implementation, the scope just gets started at the time that the controller gets created, which is after you run the handlers. 使用当前的实现,作用域只是在创建控制器时(即在运行处理程序之后)才开始。 Changing this isn't that hard, but involves changing your controller activator and have an outermost handler that starts the execution context scope (or again falling back on a dependency resolver that manages the execution context scope). 更改它并不难,但需要更改控制器激活器,并拥有一个最外层的处理程序来启动执行上下文范围(或者再次依赖于管理执行上下文范围的依赖解析器)。

One of the arguments of Mark Seemann is that it becomes hard to pass context around, which is a very valid point, as long as your components don't require this context during construction . Mark Seemann的观点之一是,很难传递上下文,这是非常正确的一点,只要您的组件在构造过程中不需要此上下文即可 But this is not a problem you'll experience when using Simple Injector, because there is an extension method that helps you with accessing the HttpRequestMessage . 但这不是使用Simple Injector时会遇到的问题,因为有一个扩展方法可以帮助您访问HttpRequestMessage So although the IDependencyResolver abstraction isn't designed for getting the contextual information, there are ways to get this contextual information. 因此,尽管IDependencyResolver抽象不是为获取上下文信息而设计的,但是仍有一些方法可以获取此上下文信息。

In the past we decided to go with an adapter for the IDependencyResolver , mainly because this was the common practice with all DI containers. 过去,我们决定为IDependencyResolver使用适配器,这主要是因为这是所有DI容器的常用做法。 I partly regret this decision, but using the SimpleInjectorDependencyResolver is now usually the easiest way of plugging in Simple Injector into Web API. 我对此决定感到部分遗憾,但是使用SimpleInjectorDependencyResolver现在通常是将Simple Injector插入Web API的最简单方法。 We considered adding a SimpleInjectorControllerActivator as well, but this had no practical benefit for most users, while we still would had to document when to use what. 我们还考虑过添加一个SimpleInjectorControllerActivator ,但这对大多数用户没有实际好处,尽管我们仍然必须记录何时使用什么。 So we decided to stick with the dependency resolver adapter; 因此,我们决定使用依赖解析器适配器。 an adapter for the activator is easily created for anyone who needs it, as you can see. 如您所见,激活器的适配器很容易为需要它的任何人创建。

For ASP.NET Core however, we went into a different direction, and as you can see in the documentation , the integration package actually contains a SimpleInjectorControllerActivator out of the box. 但是,对于ASP.NET Core,我们朝着另一个方向发展,正如您在文档中所看到的那样,集成包实际上包含一个SimpleInjectorControllerActivator In ASP.NET Core, the controller activator is the perfect interception point and due to the OWIN-like pipeline, a scope can be easily wrapped around a request. 在ASP.NET Core中,控制器激活器是完美的拦截点,并且由于具有类似于OWIN的管道,因此可以轻松地将范围包装在请求周围。 So with ASP.NET Core, the advised practice is to use the controller activator as interception point. 因此,对于ASP.NET Core,建议的做法是使用控制器激活器作为拦截点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将Simple Injector与可选的ASP.NET Core Web API集成 - Integrate Simple Injector with optional ASP.NET Core Web API Simple Injector是否支持MVC 4 ASP.NET Web API? - Does Simple Injector supports MVC 4 ASP.NET Web API? 简单的喷射器注册ASP.NET身份和Web API - Simple Injector Registration ASP.NET identity & Web API 如何解决 ASP.NET Core Web API 项目中类库的 Windsor 容器依赖项? - How to resolve Windsor container dependencies for a class library in ASP.NET Core Web API project? How can I get/create an instance of an object on Simple Injector container depending on the asp.net web api 2 session? - How can I get/create an instance of an object on Simple Injector container depending on the asp.net web api 2 session? 简单注入器 - 注册 ASP.NET 身份 - Simple Injector - Registering ASP.NET Identity 具有简单注入器的ASP.NET Core - ASP.NET Core with Simple Injector 无法解决ILogger <T> 简单的注入器ASP.NET Core 2.0 - Cannot resolve ILogger<T> Simple Injector ASP.NET Core 2.0 配置简单注入器以支持解决ASP.NET Core中间件依赖关系? - Configure Simple Injector to support resolving ASP.NET Core middleware dependencies? 简单注入器无法在 Web API 控制器中注入依赖项 - Simple Injector unable to inject dependencies in Web API controllers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM