簡體   English   中英

使用WebApi,SimpleInjector和MediatR時正確設置范圍

[英]Correctly set Scope when using WebApi, SimpleInjector and MediatR

控制者

public class LocationsController : ApiController
{
    private readonly IMediator _mediator;

    public LocationsController(IMediator mediator)
    {
        _mediator = mediator;
    }

    public IEnumerable<Place> Get()
    {
        return _mediator.Send(new GetLatestMapData<Place>());
    }
}

在首次請求Get()操作時,Handler將由SimpleInjector實例化並正確執行。

在第二個請求(例如,瀏覽器中的F5)上,它失敗,並顯示:

找不到針對類型....的請求處理程序。

容器或服務定位器配置不正確,或者處理程序未在容器中注冊。

和內部例外:

無法訪問已處置的對象。

對象名稱:'ThreadLocal對象已被處置。

OWIN啟動

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // SimpleInjector
        var container = CompositionRoot.CreateContainer();

        var config = GlobalConfiguration.Configuration;

        config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

        // Routing
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}",
            new { id = RouteParameter.Optional });

        config.EnsureInitialized();

        app.UseWebApi(config);
    }
}

用於WebAPI項目的SimpleInjector IPackage

public class Installer : IPackage
{
    public void RegisterServices(Container c)
    {
        c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

        c.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    }
}

我認為正在發生的是正確創建了Handler,然后在第一個請求之后將其處置。 現在,我不知道為什么,但是在后續請求中,不會重新創建處理程序。 我知道這是因為,如果我將WebApiRequestLifestyle更改為“作用域結束時不處置”,則它適用於每個請求:

c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(false
/*disposeInstanceWhenScopeEnds*/);

問題

  1. 是否應該將disposeInstanceWhenScopeEnds參數設置為false?
  2. 如果沒有,正確的解決方案是什么?
  3. 我看到通過創建LifetimeScopeDecorator可以解決問題 ...但是,肯定可以通過SimpleInjector WebApi集成庫提供此功能嗎? 我想念什么?

(感謝您的閱讀)

鏈接提供了有關依賴關系解析和使用IDependencyResolver / IDependencyScope接口的良好指南。

立刻,您會發現它們觸及到壽命,這往往會有些棘手。

本節特別有趣:

依賴范圍和控制器壽命

控制器是根據請求創建的。 為了管理對象生存期,IDependencyResolver使用范圍的概念。

附加到HttpConfiguration對象的依賴項解析器具有全局作用域。 Web API創建控制器時,它將調用BeginScope。 此方法返回代表子范圍的IDependencyScope。

然后,Web API在子作用域上調用GetService來創建控制器。 請求完成后,Web API會在子范圍上調用Dispose。 使用Dispose方法處理控制器的依賴項。

按照慣例,引導服務會在應用程序啟動期間發生一次,並且您知道當時可以解決所有依賴關系。 只有當工作進程關閉時(例如,沒有活動),才可以調用Dispose。

通常,我認為解決實例在生命周期中保留是很正常的,除非必須在使用后銷毀它們。 但是給出的示例說明,一旦請求完成,我們必須正確處理。 因此,我建議您使用提供的示例作為指導正確處置實例。

在使用IoC和WebApi時,這對我有幫助。 我希望這有幫助!

您需要安排您的終身范圍

碼:

container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

container.Options.LifestyleSelectionBehavior = new WebApiInjectionLifestyle();


internal class WebApiInjectionLifestyle : ILifestyleSelectionBehavior
{
    public Lifestyle SelectLifestyle(Type serviceType, Type implementationType)
    {
        return Lifestyle.Scoped;
    }
}

更多詳情

https://simpleinjector.readthedocs.io/en/latest/lifetimes.html

暫無
暫無

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

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