C# 使用简单注入器和IHttpControllerActivator解决ASP.NET Web API中的依赖关系

C# 使用简单注入器和IHttpControllerActivator解决ASP.NET Web API中的依赖关系,c#,asp.net-web-api,dependency-injection,simple-injector,C#,Asp.net Web Api,Dependency Injection,Simple Injector,我目前正在使用将依赖项解析到Asp.NETWebAPI项目中 从文档中,您可以对其进行如下配置: protected void Application_Start() { // Create the container as usual. var container = new Container(); container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(); // Regi

我目前正在使用将依赖项解析到Asp.NETWebAPI项目中

从文档中,您可以对其进行如下配置:

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.
}
应用程序\u Start
方法中,我替换了这一行:

GlobalConfiguration.Configuration.DependencyResolver =
    new SimpleInjectorWebApiDependencyResolver(container);
通过这一行:

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

我想知道
IHTTPC控制器激活器的实现是否有效,以及此方法是否有效,是否能像正常方法一样工作?

是的,您的实现是有效的

请注意不要在同一应用程序中同时使用
SimpleInjectorWebApidencyResolver
SimpleInjectorControllerActivator
。两者都启动一个
ExecutionContextScope
,这可能导致在同一web请求中有两个作用域,因此它们是互斥的

与依赖项解析程序相比,使用控制器激活器的一般优势在于,当无法创建服务时,依赖项解析程序契约强制适配器返回
null
。这是开发人员遇到的一个非常常见的问题,它经常导致混乱的异常。使用
IHttpControllerActivator
时不存在此问题,因为契约强制您返回值或引发异常

然而,Simple Injector Web API集成项目通过在请求的服务是API控制器的情况下从不返回
null
(而是抛出异常)来防止依赖解析程序出现此问题(从而隐式破坏
IDependencyResolver

使用
SimpleInjectDependencyResolver
的一个优点是,创建在执行上下文范围内操作的消息处理程序变得更加容易,因为您可以通过调用
request.GetDependencyScope()
方法触发此范围的创建。在当前实现中,作用域只是在创建控制器时启动的,这是在您运行处理程序之后。改变这一点并不难,但需要改变控制器激活器,并拥有启动执行上下文范围的最外层处理程序(或者再次依赖于管理执行上下文范围的依赖项解析程序)

Mark Seemann的一个论点是,传递上下文变得很困难,这是一个非常有效的观点,只要你的。但这并不是使用简单喷油器时会遇到的问题,因为有一个可以帮助您访问
HttpRequestMessage
。因此,尽管
idependencysolver
抽象不是为获取上下文信息而设计的,但是有一些方法可以获取上下文信息

在过去,我们决定为
idependencysolver
使用适配器,主要是因为这是所有DI容器的常见做法。我对这个决定感到部分遗憾,但使用
SimpleInjectDependencyResolver
现在通常是将SimpleInjector插入Web API的最简单方法。我们还考虑添加一个
SimpleInjectorControllerActivator
,但这对大多数用户没有实际好处,同时我们还必须记录何时使用它。所以我们决定继续使用依赖解析适配器;正如您所看到的,可以为需要激活器的任何人轻松创建适配器


然而,对于ASP.NET核心,我们进入了一个不同的方向,正如您在中所看到的,集成包实际上包含一个现成的
SimpleInjectControllerActivator
。在ASP.NET内核中,controller activator是完美的拦截点,由于类似OWIN的管道,可以轻松地将作用域包装在请求周围。因此,对于ASP.NET Core,建议的做法是使用controller activator作为拦截点。

我没有发布更新版本,而是用SimpleInjector controller activator的简化版本更新了您的问题。谢谢Steven!我需要看看asp.net核心框架,因为我想知道这种方法在asp.net核心上下文中是否仍然有效?是否有机会使用simple injector将这种方法作为默认的web api集成?在这种特定情况下,如果使用
SimpleInjectorControllerActivator
而不是
SimpleInjectorWebApiDependencyResolver
都启动
ExecutionContext
,那么使用
SimpleInjectorControllerActivator
的优势是什么?使用
ControllerActivator
可以获得哪些类型的上下文信息,而使用
DependencyResolver
无法获得这些信息?事实上,您无法从IDependencyResolver获取任何信息。。。使用IHttpControllerActivator实现,您可以访问
HttpRequestMessage
HttpControllerDescriptor
classess,以便使用int进行编写
GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator),
    new SimpleInjectorControllerActivator(container));