ServiceFilter和TypeFilter – 注入这些filter有什么区别?
ServiceFilter我们必须在Startup.cs中注册。 TypeFilter是由Microsoft.Extensions.DependencyInjection.ObjectFactory注入的,我们不需要注册那个filter。
那么当我们应该使用ServiceFilter和TypeFilter时?
好的,所以文档 :
ServiceFilter
从DI检索filter的实例。 使用ServiceFilter
而不注册filter类型会导致exception。
TypeFilterAttribute
与ServiceFilterAttribute
非常相似(并且还实现了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
您可以决定其Singleton
, Scoped
还是Transient
。 如果它的Singleton
只为所有请求创建了一个实例。
关键要记住
这是我们想要使用ServiceFilter
和Service Provider
管理的filter类型的生命周期。 如果filter具有依赖性,我们就像通常那样使用Service Provider
管理它。
如果filter具有需要从容器中解析的依赖项,请使用TypeFilterAttribute
。 它允许您执行构造函数注入 。