ServiceFilter和TypeFilter - 注入这些过滤器有什么区别?

时间:2017-04-27 12:39:05

标签: c# asp.net-core asp.net-core-mvc

ServiceFilter我们必须在Startup.cs中注册。 TypeFilter是由Microsoft.Extensions.DependencyInjection.ObjectFactory注入的,我们不需要注册那个过滤器。

那么我们何时应该使用ServiceFilter和TypeFilter?

4 个答案:

答案 0 :(得分:6)

好的,documentation

  
      
  • A ServiceFilter从DI中检索过滤器的实例。在未注册过滤器类型的情况下使用ServiceFilter会导致异常。

  •   
  • TypeFilterAttributeServiceFilterAttribute非常相似(并且还实现了IFilterFactory),但其类型不能直接从DI容器中解析。相反,它使用Microsoft.Extensions.DependencyInjection.ObjectFactory实例化该类型。

  •   
     

由于存在这种差异,使用TypeFilterAttribute 引用的类型不需要先在容器中注册(但它们的容器仍然会满足它们的依赖关系)。

答案 1 :(得分:5)

根据Pro ASP.NET Core MVC 2书。第19章:过滤器,第615页

  

使用TypeFilter属性时,过滤器的新实例   为每个请求创建一个类。这与行为相同   直接应用过滤器作为属性,但TypeFilter除外   attribute允许过滤器类声明依赖项   通过服务提供商解决。 ServiceFilter属性   更进一步,使用服务提供商创建过滤器   宾语。这允许将过滤器对象置于生命周期内   管理层。

差异 由于ServiceFilter使用ServiceProvider来解析相关过滤器的实例,因此您可以控制在启动类中注册的过滤器的生命周期:

services.AddSingleton<TimeFilter>();

从上面的代码行开始,TimeFilter只会为MVC应用程序生命周期(不是每个http请求生命周期或客户端请求它)创建一次,它将用于所有http请求,即使用TypeFilter是不可能的,因为在实例化和处理TypeFilter下使用的过滤器时,无法指示MVC框架。

如果过滤器注册为Singleton,则只创建该过滤器的一个实例,这意味着CLR的工作量减少,这与TypeFilter为每个http创建过滤器类的新实例的情况不同请求。

使用  假设您在两个操作方法上应用了TypeFilter,对于每个HTTP请求,将创建该TypeFilter的新实例,将调用构造函数并注入依赖项(您可以控制生命使用Service Provider)的依赖循环。相反,使用ServiceFilter,您可以决定是Singleton还是Scoped还是Transient。如果它是Singleton,则只为所有请求创建一个实例。

关键要记住

这是我们想要使用ServiceFilterService Provider管理的过滤器类型的生命周期。如果过滤器具有依赖性,我们已经像通常那样使用Service Provider来管理它。

答案 2 :(得分:3)

ServiceFilter和TypeFilter都是使用依赖注入构建的。

根据this,使用Microsoft.Extensions.DependencyInjection.ObjectFactory实例化TypeFilter,最终允许您自己提供构造函数参数(您可以在其构造函数中看到 Arguments 参数)。它还解决了你不能提供的问题。

所以你可以这样做:

public class AttachMetadataAttribute : Attribute, IAsyncActionFilter
{
    public AttachMetadataAttribute(SomeType someValue, ISomeService service)
        {
        }
}

你可以这样使用:

[TypeFilter(typeof(AttachMetadataAttribute),
    IsReusable = true,
    Order = 10,
    Arguments = new object[] { someValue})]

所以这里第一个参数(someValue)由你提供,服务由容器注入。

注意:小心 IsReusable 。如果它设置为true,则注入的服务仅创建一次。

答案 3 :(得分:0)

如果您的过滤器具有您需要从容器中解析的依赖项,请使用TypeFilterAttribute。它允许你to perform constructor injection