ServiceFilter和TypeFilter – 注入这些filter有什么区别?

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

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

好的,所以文档 :

  • ServiceFilter从DI检索filter的实例。 使用ServiceFilter而不注册filter类型会导致exception。

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

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

ServiceFilter和TypeFilter都是使用dependency injection构造的。

根据这个 ,TypeFilter使用Microsoft.Extensions.DependencyInjection.ObjectFactory进行实例化,最终允许您自己提供构造函数参数(您可以在其构造函数中看到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,则注入的服务仅创建一次。

根据Pro ASP.NET Core MVC 2的书。 第19章: filter ,第615页

使用TypeFilter属性时,会为每个请求创建一个新的filter类实例。 这与将filter直接应用为属性的行为相同,只是TypeFilter属性允许filter类声明通过服务提供程序解析的依赖项。 ServiceFilter属性更进一步,使用服务提供程序创建filter对象。 这允许filter对象也被置于生命周期管理之下。

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

 services.AddSingleton(); 

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

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

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

关键要记住

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

如果filter具有需要从容器中解析的依赖项,请使用TypeFilterAttribute 。 它允许您执行构造函数注入 。