代码之家  ›  专栏  ›  技术社区  ›  Johan

IHTTPC控制器激活器中的控制器处理

  •  0
  • Johan  · 技术社区  · 6 年前

    我有个习惯 IHttpControllerActivator 对于我正在使用的WebAPI控制器和简单的注入器:

    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()));

    我需要处理控制器的任何处置,还是由框架处理?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Steven    6 年前

    我需要处理控制器的任何处置吗

    简单的答案是:只要使用 RegisterWebApiControllers() 扩展方法,不需要处理控制器的处置。

    长话短说,当你打电话 RegisterWebApiControllers ,简单的注入器实际上 处理你的控制器,但你会得到一个 VerificationException 当你超越 Dispose(bool) 当你打电话的时候 Container.Verify() .

    原因如下:简单的注入器只会在注册为 Scoped Singleton . Transient 注册永远不会被处理。这个 注册eBapicontrollers 但是,扩展方法将控制器注册为 瞬变的 .

    登记一次性物品时 瞬变的 在简单的注入器中,它通常会导致 DisposableTransientComponent 警告,当 Verify 被称为。然而,由于 ApiController 基类确实实现了 IDisposable ,但是 处置(布尔) 方法是no操作,除非派生控制器显式重写,否则不处理它不是问题 处置(布尔) .

    正因为如此, 注册eBapicontrollers 只需在进行注册时抑制此警告。当它发现派生的控制器类 覆盖 处置(布尔) 但是,它将放弃抑制,您将看到 Verify() 警告您此可弃类型,因为不处置此类类型将是一个问题。

    这种行为背后的想法是,在控制器上实际实现可支配逻辑的需求非常少,因为控制器本身通常不必处理非托管资源。这通常是低级组件所做的事情,但是,如果注册正确,这些组件将由简单的注入器处理。如果您有一个具有dispose逻辑的控制器,那么您应该考虑对其进行重构,并将该资源从控制器移到另一个组件中。

    在极少数情况下,在控制器上使用dispose逻辑最有意义,您必须:

    • 将特定控制器注册为 范围
    • 或者取消该控制器上的警告,并将该控制器注册为在请求的活动状态下进行处理 Scope 使用 container.RegisterInitializer<MyControllerType>(c => Lifestyle.Scope.RegisterForDisposal(container, c));