2016-09-22 67 views
0

控制器使用的WebAPI,SimpleInjector和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>()); 
    } 
} 

在獲取()動作的第一請求時,正確設定範圍內,所述處理程序被實例化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); 
    } 
} 

SimpleInjector IPackage爲的WebAPI項目

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

     c.RegisterWebApiControllers(GlobalConfiguration.Configuration); 
    } 
} 

我認爲發生的事情是處理程序正確地創建,然後將第一個請求後丟棄。 現在,我不知道爲什麼,但在隨後的請求中,處理程序不會重新創建。我知道這是因爲如果我改變WebApiRequestLifestyle爲「當範圍結束不處理」,它爲每一個請求:

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

問題

  1. 我應該保持disposeInstanceWhenScopeEnds參數設置爲false?
  2. 如果不是,那麼正確的解決方案是什麼?
  3. 我看到這已經是solved before by creating a LifetimeScopeDecorator ...但是,當然這個功能已經由SimpleInjector WebApi集成庫提供了嗎?我錯過了什麼?

(謝謝你的閱讀)

+0

請添加相應的堆棧跟蹤, – Steven

回答

0

link提供解決依賴良好的指導和使用的IDependencyResolver/IDependencyScope接口。

立即你會看到他們觸及到生活中的一些往往會變得棘手的問題。

這部分特別有趣的是:

Dependenecy範圍和控制器壽命

控制器是每個請求創建。爲了管理對象的生命週期,IDependencyResolver使用範圍的概念。

連接到HttpConfiguration對象的依賴關係解析器具有全局作用域 。當Web API創建控制器時,它會調用BeginScope。 此方法返回一個表示子範圍的IDependencyScope。

Web API然後調用子範圍上的GetService來創建控制器 。當請求完成時,Web API調用 子作用域上的Dispose。使用Dispose方法處理控制器的依賴關係 。

通常在應用程序啓動過程中會引導一次服務,因爲您知道當時解決任何依賴關係。只有當工作進程關閉時(例如沒有活動),纔會調用dispose。

通常我認爲解決的實例在生命週期中保持非常正常,除非必須在使用後銷燬它們。但給出的例子說明,一旦請求完成,我們就必須正確處理。因此,我建議您使用提供的示例作爲指導,正確處理您的實例。

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

0

您需要安排你的一生範圍的

代碼:

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