Yesterday I talked about a problem we encountered when trying to inject a scoped service into ASP.NET Core middleware.
The middleware used was convention based middleware, one of the ways to construct middleware in ASP.NET Core.
With convention based middleware there isn’t a base class or interface to implement. The only rules your middleware class needs to apply to are:
- It has a public constructor with a parameter of type RequestDelegate.
- It contains a public method named
Invoke
orInvokeAsync
. This method must:- Return a
Task
. - Accept a first parameter of type HttpContext.
- Return a
Convention based middleware is registered with a singleton lifetime, so you can only constructor injection for the dependencies with a singleton lifetime. For transient and scoped dependencies you need to add extra parameters to the InvokeAsync()
method:
There is a log of magic going on when using convention based middleware and it shouldn’t be a surprise that people are not aware of its behavior.
If you want full control on the middleware construction and avoid any kind of convention-based “magic” you can use the factory based middleware instead.
Now we need a class that implements the IMiddleware interface:
A transient or scoped dependency can now be injected through the constructor:
The only thing remaining to do is to register our factory based middleware with a transient lifetime: