Life cycle and dependency injection

As we already said, Dependency injection is a core technique in ASP.NET Core. Filters usually rely on other components to provide the filter logic. Before discussing injecting dependencies in filters, we need to understand the life cycle process. In general, when we apply a filter as an attribute, the life cycle of the filter is restricted to the request, which means that it is reinitialized for each request. The ServiceFilter attribute provides a valid alternative to overriding this kind of behavior. Therefore, the ServiceFilter attribute uses the service provider to create filter objects, which means that our filter is managed just like any other service declared through the dependency injection system of ASP.NET Core.

For example, let's consider the implementation of the CustomActionFilter class we defined previously:

using Microsoft.AspNetCore.Mvc.Filters;

namespace SampleAPI.Filters
{
public class CustomActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// do something before the action executes
}

public void OnActionExecuted(ActionExecutedContext context)
{
// do something after the action executes
}
}
}

It is possible to initialize the CustomActionFilter type using the AddSingleton extension method in the Startup class:

...
public void
ConfigureServices(IServiceCollection services)
{
services
.AddSingleton<IOrderRepository, MemoryOrderRepository>()
.AddSingleton<CustomActionFilter>()
...
}
...

We can then use it in our controllers or action methods, as follows:

...
[ServiceFilter(typeof(CustomActionFilter))]
public class OrderController : ControllerBase
{
...

This approach guarantees that we override the life cycle of the filters by explicitly defining the life cycle type in the service provider. Therefore, the filter pipeline is integrated and initialized using the dependency injection engine of ASP.NET Core. Moreover, it is also possible to resolve filter dependencies using the dependency injection engine. There are two injection techniques related to filters:

  • Using the ServiceFilter technique
  • Using the TypeFilterAttribute technique

As we saw previously, the ServiceFilter type adds the instance of filters in the service provider. It is possible to inject the dependency into a filter by adding it to the constructor. We can do this using constructor injection:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;

namespace SampleAPI.Filters
{
public class CustomActionFilter: IActionFilter
{
private readonly ILogger _logger;

public CustomActionFilter(ILogger logger)
{
_logger = logger;
}

public void OnActionExecuting(ActionExecutingContext context)
{
_logger.LogInformation("Logging OnActionExecuting");
}

public void OnActionExecuted(ActionExecutedContext context)
{
_logger.LogInformation("Logging OnActionExecuted");
}
}

The preceding code injects the ILogger interface into the constructor and uses the exposed LogInformation extension method. It is also possible to not pass through the service provider using TypeFilterAttribute by referring to our filter using the type and not the instance. We do this by declaring another class that extends TypeFilterAttribute, which passes the type of our filter to the base class:

public class CustomActionFilterAttribute : TypeFilterAttribute
{
public CustomActionFilterAttribute() : base(typeof(CustomActionFilter))
{
}
}

Then it applies the attribute to the target controller:

...
[CustomActionFilterAttribute]
public class OrderController : ControllerBase
{
...

The CustomActionFilterAttribute class extends the TypeFilterAttribute base class and calls the base constructor by referring to the CustomActionFilter type. This approach enhances the usability of filter attributes that depend on other classes. Now that we have a complete understanding of filters and know how to apply them to the filter pipeline, we can take a look at some concrete use cases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.147.124