使用WebApi、SimpleInjector和Mediator时正确设置Scope
本文关键字:设置 Scope Mediator WebApi SimpleInjector 使用 | 更新日期: 2023-09-27 18:08:23
控制器
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((操作时,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 IP包
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*/);
问题
- 我应该将
disposeInstanceWhenScopeEnds
参数设置为false吗 - 如果没有,正确的解决方案是什么
- 我看到这个问题以前已经通过创建LifetimeScopeRecorder解决了。。。但是,这个功能肯定已经由SimpleInjector WebApi集成库提供了吗?我错过了什么
(感谢您的阅读(
此链接提供了有关依赖项解析和使用IDependencyResolver/IDependencyScope接口的良好指导。
你会立刻发现,它们涉及的寿命往往会变得有点棘手。
这一部分特别有趣:
依赖范围和控制器寿命
控制器是根据请求创建的。为了管理对象寿命,IDdependencyResolver使用范围的概念。
附加到HttpConfiguration对象的依赖关系解析程序具有全球范围。当Web API创建一个控制器时,它会调用BeginScope。此方法返回一个表示子作用域的IDependencyScope。
然后Web API在子作用域上调用GetService以创建控制器。当请求完成时,Web API在子范围。使用Dispose方法处理控制器的依赖关系。
按照惯例,引导服务会在应用程序启动期间发生一次,并且如您所知,会在那时解决任何依赖关系。只有当工作进程关闭时(例如,没有活动(,才会调用dispose。
通常,我认为已解决的实例在生命周期中保留是很正常的,除非它们在使用后必须销毁。但是,给出的示例说明,一旦请求完成,我们就必须正确处理。因此,我建议您使用所提供的示例作为指导,正确处理您的实例。
这对我使用IoC和WebApi时有所帮助。我希望这能有所帮助!
您需要安排您的Lifetime范围
代码:
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