簡體   English   中英

使用Simple Injector和IHttpControllerActivator解決ASP.NET Web API中的依賴項

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

我目前正在使用Simple Injector來解決對Asp.Net Web Api項目的依賴。

您可以從文檔中進行如下配置:

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.
}

這里的要點是注冊Web Api控制器並設置自定義依賴項解析器。

但是,我剛剛閱讀了Mark Seemann的有關如何在Asp.Net Web Api中配置依賴項注入的文章:

從這些文章中,我了解到有比實現IDependencyResolver更好的選擇來解決Web Api依賴關系。 另一種選擇是創建IHttpControllerActivator的實現,該實現充當IoC容器上的適配器。

這是我使用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);
    }
}

Application_Start方法中,我替換了以下行:

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

通過此行:

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

我想知道IHttpControllerActivator的實現是否有效,並且這種方法是否有效,是否會像普通方法一樣有效?

是的,您的實施有效。

請注意不要在同一應用程序中同時使用SimpleInjectorWebApiDependencyResolverSimpleInjectorControllerActivator 兩者都啟動一個ExecutionContextScope ,這可能導致在同一Web請求中具有兩個范圍,因此它們是互斥的。

與依賴解析器相比,使用控制器激活器的一般優勢在於,依賴解析器協定強制適配器在無法創建服務時返回null 這是開發人員遇到的一個非常常見的問題,它通常導致令人困惑的控制器沒有默認的構造函數異常。 使用IHttpControllerActivator時不存在此問題,因為該合同會強制您返回值或引發異常。

但是,Simple Injector Web API集成項目通過在請求的服務是API控制器的情況下從不返回null (而是拋出異常)(從而隱式打破IDependencyResolver的合同)來避免依賴項解析器出現此問題。

使用SimpleInjectorDependencyResolver一個優點是,創建在執行上下文范圍內運行的消息處理程序變得更加容易,因為您可以通過調用request.GetDependencyScope()方法來觸發此范圍的創建。 使用當前的實現,作用域只是在創建控制器時(即在運行處理程序之后)才開始。 更改它並不難,但需要更改控制器激活器,並擁有一個最外層的處理程序來啟動執行上下文范圍(或者再次依賴於管理執行上下文范圍的依賴解析器)。

Mark Seemann的觀點之一是,很難傳遞上下文,這是非常正確的一點,只要您的組件在構造過程中不需要此上下文即可 但這不是使用Simple Injector時會遇到的問題,因為有一個擴展方法可以幫助您訪問HttpRequestMessage 因此,盡管IDependencyResolver抽象不是為獲取上下文信息而設計的,但是仍有一些方法可以獲取此上下文信息。

過去,我們決定為IDependencyResolver使用適配器,這主要是因為這是所有DI容器的常用做法。 我對此決定感到部分遺憾,但是使用SimpleInjectorDependencyResolver現在通常是將Simple Injector插入Web API的最簡單方法。 我們還考慮過添加一個SimpleInjectorControllerActivator ,但這對大多數用戶沒有實際好處,盡管我們仍然必須記錄何時使用什么。 因此,我們決定使用依賴解析器適配器。 如您所見,激活器的適配器很容易為需要它的任何人創建。

但是,對於ASP.NET Core,我們朝着另一個方向發展,正如您在文檔中所看到的那樣,集成包實際上包含一個SimpleInjectorControllerActivator 在ASP.NET Core中,控制器激活器是完美的攔截點,並且由於具有類似於OWIN的管道,因此可以輕松地將范圍包裝在請求周圍。 因此,對於ASP.NET Core,建議的做法是使用控制器激活器作為攔截點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM