`ActionFiliter`中的依赖注入与调用`Activator.CreateInstance()`

时间:2017-06-04 16:27:46

标签: dependency-injection asp.net-core asp.net-core-mvc

有时需要在ActioFilter中使用依赖注入,或者在操作API之前或之后运行的其他属性或结果是不可避免的。但是,它是通过使用typeof关键字将要注入的类型传递给属性来执行的。为了简化这种情况,当对接口进行各种实现时,我发现手动实例化类型要比使用内置依赖注入框架简单得多。例如:

public TestAttribute: Attribute, IActionFilter {
   private Type injectionType;
   public TestAttribute(Type injectionType){
     ... 
   }
   ...
   public void OnActionExecuting(ActionExecutingContext context) {
       InjectedTypeInterface injectedTypInterface = (InjectedTypeInterface) Activator.CreateInstance(injectedType, arg1, arg2, ...);
       ...
   }
}

我想知道,从其他人的角度来看,这种方法会导致使用内置依赖注入框架的问题吗? (在这种情况下,注入的实现将总是瞬态,而不是Scoped或Singleton)

1 个答案:

答案 0 :(得分:2)

我不建议做Activator.CreateInstance的路线,这里有一些理由可以避免它并坚持官方方式:

  1. 您需要传递参数的所有实例(即您要实例化的类型具有其他依赖关系)
  2. 以这种方式创建的实例不会被作用域容器跟踪。这也意味着,它不会自动被处置(更新的注释这当然只会在请求结束时服务实现IDisposable接口时发生)而是被处置在未来某个不确定的时间,当GC开始并且将保持资源开放时间超过预期时(即保持连接或文件句柄打开的时间更长),除非您明确处置它
  3. 就像您已经认识到的那样,您无法使用作用域和单例实例
  4. 对于您的具体示例,有更简单的方法从DI获取特定实例 - 除了官方支持的方式(Filters - Dependency Injection) - 您也可以从HttpContext解决,假设您有权访问它在您使用的过滤器类型中。

    适用于ActionFilter / IActionFilter

    public void OnActionExecuting(ActionExecutingContext context) {
        InjectedTypeInterface injectedTypInterface = context.HttpContext
            .RequestServices.GetService<InjectedTypeInterface>();
       ...
    }