ServiceFilter我们必须在Startup.cs中注册。 TypeFilter是由Microsoft.Extensions.DependencyInjection.ObjectFactory注入的,我们不需要注册那个过滤器。
那么我们何时应该使用ServiceFilter和TypeFilter?
答案 0 :(得分:6)
好的,documentation:
A
ServiceFilter
从DI中检索过滤器的实例。在未注册过滤器类型的情况下使用ServiceFilter
会导致异常。
TypeFilterAttribute
与ServiceFilterAttribute
非常相似(并且还实现了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
,则只为所有请求创建一个实例。
关键要记住
这是我们想要使用ServiceFilter
和Service 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。