2016-09-22 26 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