我为自己的Web api控制器使用了自定义IHttpControllerActivator
,并与简单的注入器一起使用:
public sealed class ApiControllerActivator : IHttpControllerActivator
{
private readonly Container _container;
private readonly IHttpControllerActivator _original;
public ApiControllerActivator(Container container, IHttpControllerActivator original)
{
_container = container;
_original = original;
}
public IHttpController Create(HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = CreateController(request, controllerDescriptor, controllerType);
// request.RegisterForDispose(...); required?
return controller;
}
private IHttpController CreateController(HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
if (controllerType.IsSubclassOf(typeof(WebApiController)))
{
return (IHttpController) _container.GetInstance(controllerType);
}
return _original.Create(request, controllerDescriptor, controllerType);
}
}
注册:
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new ApiControllerActivator(container, GlobalConfiguration.Configuration.Services.GetHttpControllerActivator()));
我需要处理控制器的任何处置,还是由框架处理?
答案 0 :(得分:1)
我需要处理控制器的任何处置
简单的答案是:只要使用RegisterWebApiControllers()
扩展方法注册Web API控制器,就无需处理控制器。
长答案是,当您调用RegisterWebApiControllers
时,Simple Injector实际上将不完全处置您的控制器,但是当您覆盖{{ 1}},当您致电VerificationException
时在其中一个控制器中。
原因如下:Simple Injector仅在将一次性类注册为Dispose(bool)
或Container.Verify()
时处置一次性类。 Scoped
注册永远不会被丢弃。但是,Singleton
扩展方法将控制器注册为Transient
。
在Simple Injector中注册一次性RegisterWebApiControllers
时,通常会在调用Transient
时引发Transient
警告。但是,由于DisposableTransientComponent
基类确实实现了Verify
,但是它的ApiController
方法是no-op,不处理它不是问题,除非派生的控制器显式重写{ {1}}。
因此,IDisposable
仅在进行注册时禁止显示此警告。但是,当发现派生的控制器类确实覆盖Dispose(bool)
时,它将丢弃该抑制,并且您会看到Dispose(bool)
会警告您有关此可抛弃类型的信息,因为未处置此类类型会是个问题。
此行为背后的想法是,实际上很少需要在控制器上实现一次性逻辑,因为控制器本身通常不必处理非托管资源。低级组件通常会执行此操作,但是如果正确注册,这些组件将由Simple Injector处置。如果您的控制器具有处理逻辑,则应考虑对其进行重构,并将该资源从控制器中移出到另一个组件中。
在极为罕见的情况下,在控制器本身上配置逻辑是最有意义的,您要么必须:
RegisterWebApiControllers
Dispose(bool)
在请求的活动Verify()
中注册该控制器以进行处理