2017-06-04 30 views
0

需要有时使用依赖注入在ActioFilter或其他属性之前或动作API或结​​果后运行是不可避免的。然而,它是通过使式被注入到使用typeof关键字属性进行。为了简化的情况下,具有用于一个接口各种实现时,我发现它更简单手动实例化类型不是使用内置的依赖注入框架。例如:依赖注入在`ActionFiliter`与调用`Activator.CreateInstance()`

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

我想知道,从这里其他人的地步,那这种方法的原因的问题,使用内置的依赖注入框架不会? (注射执行将始终是瞬态在这种情况下,而不是作用域或单身)

回答

2

我不建议这样做的Activator.CreateInstance路线,这里有一些原因,以避免它与官方的方式坚持:

  1. 您需要传递参数的所有实例(即,要实例化的类型具有其他依赖项)的所有实例
  2. 以此方式创建的实例不受作用域容器的跟踪。这也意味着,它不会自动得到配置(更新注这当然如果服务实现IDisposable接口才会发生)在请求结束,而是在将来的某个不确定的时间来布置,在GC时踢在并会不断的资源开放长于预期(即保持连接或文件句柄打开长于预期的),除非你处置它明确
  3. 像你已经认识到,你不能用作用域和单实例这样做

为了您的具体的例子,有更容易的方式来获得从DI特定实例 - 除了官方支持的方式(Filters - Dependency Injection) - 你可以人从HttpContext所以解决,假设您可以访问它正在使用的过滤器的类型。

对于ActionFilter/IActionFilter

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

嗯,差不多你的答案中最惊人的部分是数字2。因为我真的没有意识到这一点。如果我实现了一次性使用并在“使用”块中使用它,您认为什么?第一个对我来说没有问题,因为我需要将参数手动传递给构造函数,这是无法使用DI完成的。 – Arrrr

+1

是否有来自DI的任何参数依赖关系?如果是这样,使用工厂模式可能是更好的解决方案。然后你可以注入依赖到工厂,并有一个方法'公共T创建(字符串参数1,int param2)'。它仍然没有被跟踪(但它的依赖是)。另外,如果参数是Attribute属性,则可以使用上面的'TypeFilter'。如果它们是动态的,那么以前提到的工厂模式 – Tseng

+0

我尝试过使用DI,但它似乎不适用于内置框架。因为,过滤器的注入类型因动作而异,我不能像这样指定它。 – Arrrr