Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ServiceFilter and TypeFilter - what is the difference in injection those filters?

ServiceFilter we must register in Startup.cs. TypeFilter is injected by Microsoft.Extensions.DependencyInjection.ObjectFactory, we don't need to register that filter.

So when we should use ServiceFilter and when TypeFilter ?

like image 983
MrChudz Avatar asked Apr 27 '17 12:04

MrChudz


People also ask

What is difference between middleware and filters in .NET core?

Middleware only has access to the HttpContext and anything added by preceding middleware. In contrast, filters have access to the wider MVC context, so can access routing data and model binding information for example.

What is service filter .NET core?

Filters in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Authorization, preventing access to resources a user isn't authorized for. Response caching, short-circuiting the request pipeline to return a cached response.

How do I use authorized filter in net core?

Authorization filters in ASP.NET Core MVC Authorization filters are executed at the beginning of the request pipeline, before any other filters have been executed. They are used to verify a user's credentials in order to identify whether or not the user is allowed to access the resource.


3 Answers

According to Pro ASP.NET Core MVC 2 book (download). Chapter 19: Filters, page # 615

When using the TypeFilter attribute, a new instance of the filter class is created for every request. 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. The ServiceFilter attribute goes a step further and uses the service provider to create the filter object. 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:

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.

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.

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). In contrast, with ServiceFilter you decide if its Singleton or Scoped or Transient. If its Singleton then only one instance is created for all the requests.

KEY THING TO REMEMBER

It’s the filter type’s life cycle that we want to manage by using ServiceFilter and Service Provider. If the filter has dependencies, we already manage that using Service Provider like we normally do.

like image 86
Yawar Murtaza Avatar answered Oct 12 '22 13:10

Yawar Murtaza


Ok, so documentation:

  • A ServiceFilter retrieves an instance of the filter from DI. Using ServiceFilter without registering the filter type results in an exception.

  • TypeFilterAttribute is very similar to ServiceFilterAttribute (and also implements IFilterFactory), but its type is not resolved directly from the DI container. Instead, it instantiates the type by using 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).

like image 30
Set Avatar answered Oct 12 '22 12:10

Set


Both ServiceFilter and TypeFilter are constructed using dependency injection.

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). 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.

Note: Careful about IsReusable. If it's set to true the injected service is only created once.

like image 13
Alireza Avatar answered Oct 12 '22 13:10

Alireza