[英]ServiceFilter and TypeFilter - what is the difference in injection those filters?
ServiceFilter we must register in Startup.cs. 我们必须在Serviceup.cs中注册ServiceFilter。 TypeFilter is injected by Microsoft.Extensions.DependencyInjection.ObjectFactory, we don't need register that filter.
TypeFilter是由Microsoft.Extensions.DependencyInjection.ObjectFactory注入的,我们不需要注册该过滤器。
So when we should use ServiceFilter and when TypeFilter ? 那么什么时候应该使用ServiceFilter和何时使用TypeFilter?
According to Pro ASP.NET Core MVC 2 book. 根据Pro ASP.NET Core MVC 2的书。 Chapter 19: Filters , page # 615
第19章: 过滤器 ,第615页
When using the TypeFilter attribute, a new instance of the filter class is created for every request.
使用TypeFilter属性时,将为每个请求创建过滤器类的新实例。 This is the same behavior as applying a filter directly as an attribute, except that the TypeFilter attribute allows a filter class to declare dependencies that are resolved through the service provider.
这与将过滤器直接用作属性的行为相同,不同之处在于TypeFilter属性允许过滤器类声明通过服务提供者解析的依赖项。 The ServiceFilter attribute goes a step further and uses the service provider to create the filter object.
ServiceFilter属性更进一步,并使用服务提供者来创建过滤器对象。 This allows filter objects to be placed under life-cycle management as well.
这也允许将过滤器对象置于生命周期管理下。
THE DIFFERENCE Since the ServiceFilter
uses the ServiceProvider
to resolve the instance of the filter in question, you have control over the lifecycle of the filter which is registered in the startup class: 区别由于
ServiceFilter
使用ServiceProvider
来解决所涉及的筛选器实例,因此您可以控制在启动类中注册的筛选器的生命周期:
services.AddSingleton<TimeFilter>();
From above line of code, the TimeFilter
will only be created once for the MVC application lifecycle (not for each http request life cycle or when client asks for it) that will serve for all the http requests which is not possible using TypeFilter
because there is no way you can instruct MVC framework when to instantiate and dispose the filter used under TypeFilter
. 从上面的代码行中,将仅为MVC应用程序生命周期创建一次
TimeFilter
(而不是为每个http请求生命周期或当客户要求时)创建一次,以便为所有http请求提供服务,而使用TypeFilter
是不可能的,因为存在您无法指示MVC框架何时实例化和配置TypeFilter
下使用的过滤器。
If the filter is registered as Singleton
then only one instance of that filter is created which means less work for CLR which is unlike in case of TypeFilter
that creates new instance of filter class for each http request. 如果将过滤器注册为
Singleton
则仅创建该过滤器的一个实例,这意味着CLR的工作量减少,这与TypeFilter
为每个http请求创建过滤器类的新实例的情况不同。
THE USAGE Say you have a TypeFilter
applied on two action methods, for each HTTP request, a new instance of that TypeFilter
will be created, the constructor will be called and dependencies will be injected (you can control the life cycle of dependencies using the Service Provider
). 用法假设您将
TypeFilter
应用于两个操作方法,对于每个HTTP请求,将创建该TypeFilter
的新实例,将调用构造函数并注入依赖项(您可以使用Service Provider
控制依赖项的生命周期Service Provider
)。 In contrast, with ServiceFilter
you decide if its Singleton
or Scoped
or Transient
. 相反,使用
ServiceFilter
可以确定其Singleton
还是Scoped
或Transient
。 If its Singleton
then only one instance is created for all the requests. 如果其为
Singleton
则仅为所有请求创建一个实例。
KEY THING TO REMEMBER 要记住的关键
It's the filter type's life cycle that we want to manage by using ServiceFilter
and Service Provider
. 我们要使用
ServiceFilter
和Service Provider
来管理过滤器类型的生命周期。 If the filter has dependencies, we already manage that using Service Provider
like we normally do. 如果过滤器具有依赖项,则我们已经像平常一样使用
Service Provider
管理它。
Ok, so documentation : 好的,所以文档 :
A
ServiceFilter
retrieves an instance of the filter from DI.ServiceFilter
从DI检索过滤器的实例。 UsingServiceFilter
without registering the filter type results in an exception.在未注册过滤器类型的情况下使用
ServiceFilter
导致异常。
TypeFilterAttribute
is very similar toServiceFilterAttribute
(and also implements IFilterFactory), but its type is not resolved directly from the DI container .TypeFilterAttribute
与ServiceFilterAttribute
非常相似(并且也实现IFilterFactory), 但是不能直接从DI容器解析其类型 。 Instead, it instantiates the type by usingMicrosoft.Extensions.DependencyInjection.ObjectFactory
.而是使用
Microsoft.Extensions.DependencyInjection.ObjectFactory
实例化类型。Because of this difference, types that are referenced using the
TypeFilterAttribute
do not need to be registered with the container first (but they will still have their dependencies fulfilled by the container).由于存在这种差异,使用
TypeFilterAttribute
引用的类型不需要先在容器中注册 (但它们仍将由容器来满足其依赖关系)。
Both ServiceFilter and TypeFilter are constructed using dependency injection. ServiceFilter和TypeFilter都是使用依赖项注入构造的。
According to this the TypeFilter is instantiated using Microsoft.Extensions.DependencyInjection.ObjectFactory
which ultimately allows you to provide constructor parameters yourself (You can see an Arguments parameter in its constructor). 根据该对TypeFilter使用实例化
Microsoft.Extensions.DependencyInjection.ObjectFactory
最终允许您将自己提供构造函数的参数(你可以看到它的构造函数的自变量参数)。 It also resolves the ones you don't provide. 它还可以解决您不提供的服务。
So you can do something like this: 因此,您可以执行以下操作:
public class AttachMetadataAttribute : Attribute, IAsyncActionFilter
{
public AttachMetadataAttribute(SomeType someValue, ISomeService service)
{
}
}
And you can use that like this: 您可以这样使用:
[TypeFilter(typeof(AttachMetadataAttribute),
IsReusable = true,
Order = 10,
Arguments = new object[] { someValue})]
So here the the first parameter (someValue) is provided by you and the service gets injected by the container. 因此,这里第一个参数(someValue)由您提供,服务由容器注入。
Note: Careful about IsReusable . 注意:注意IsReusable 。 If it's set to true the injected service is only created once.
如果将其设置为true,则注入的服务仅创建一次。
If your filter has dependencies that you need to resolve from the container, then use TypeFilterAttribute
. 如果您的过滤器具有需要从容器中解析的依赖项,请使用
TypeFilterAttribute
。 It allows you to perform constructor injection . 它允许您执行构造函数注入 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.