控制器
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,然后在第一个请求之后处理。 现在,我不知道为什么,但在后续请求中,不会重新创建Handler。我知道这一点,因为如果我将WebApiRequestLifestyle更改为“在范围结束时不进行处理”,则它适用于每个请求:
c.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle(false
/*disposeInstanceWhenScopeEnds*/);
问题
disposeInstanceWhenScopeEnds
参数设置为false吗?(谢谢你阅读)
答案 0 :(得分:0)
这个link为依赖解析和使用IDependencyResolver / IDependencyScope接口提供了很好的指导。
你会立刻看到他们触及的生命跨度往往会有点棘手。
本节特别有趣:
依赖范围和控制器寿命
根据请求创建控制器。要管理对象的生命周期, IDependencyResolver使用范围的概念。
附加到HttpConfiguration对象的依赖项解析器具有 全球范围。当Web API创建控制器时,它会调用BeginScope。 此方法返回表示子范围的IDependencyScope。
Web API然后在子范围上调用GetService来创建 控制器。请求完成后,Web API将调用Dispose 儿童范围。使用Dispose方法处理控制器 的依赖关系。
在应用启动过程中,传统的引导服务会发生一次,因为您知道在那时解决任何依赖关系。只有当工作进程关闭时(例如,没有活动),才会调用dispose。
通常我认为解决的实例保留生命周期是很正常的,除非它们必须在使用后被销毁。但是给出的例子解释了我们必须在请求完成后正确处理。因此,我建议您使用提供的示例正确处理您的实例。
这在使用IoC和WebApi时帮助了我。我希望这有帮助!
答案 1 :(得分: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