Daily Knowledge Drop
It is possible to manually pass parameters to a middleware component
when configuring the component and middleware pipeline on startup. Manually passed parameters can be used in conjunction with parameters provided by the dependency injection container.
Middleware configuration
In the below examples, to demonstrate a parameter provided by the DI container, a simple ApplicationConfiguration class has been configured with the dependency injection container as transient:
builder.Services.AddTransient(typeof(ApplicationConfiguration));
Distinct parameters
If a middleware component has parameters which are of distinct types
then when adding the component to the middleware pipeline, the parameters can be specified in any order
.
Below, the DistinctParamMiddleware constructor has distinct types as parameters:
public class DistinctParamMiddleware
{
private readonly int _version;
private readonly string _name;
private readonly ApplicationConfiguration _setup;
private readonly RequestDelegate _next;
// all distinct parameters
public DistinctParamMiddleware(RequestDelegate next, string name,
int version, ApplicationConfiguration setup)
{
_version = version;
_name = name;
_setup = setup;
_next = next;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine($"In {nameof(DistinctParamMiddleware)} with" +
$"application name: '{_name}' and version: '{_version}'");
await _next(context);
}
}
Parameters can manually be passed in when using the UseMiddleware
method on startup, and because the parameter types are distinct, the manually supplied parameters can be passed in any order:
app.UseMiddleware<DistinctParamMiddleware>( 1, "MiddlewareParamDemo");
In the above, RequestDelegate
and ApplicationConfiguration
are supplied from the dependency injection container, while the string
and int
parameters are supplied manually
. Even though the constructor has the string parameter specified first, and then the int parameter, when invoking the UseMiddleware method, the values are not supplied in that order.
Non-distinct parameters
When dealing with a middleware component which does not have parameters which are of distinct types
, then the parameter values need to be supplied in order:
public class DuplicateTypeParamMiddleware
{
private readonly ApplicationConfiguration _setup;
private readonly RequestDelegate _next;
private readonly string _name;
private readonly string _version;
// two string parameters
public DuplicateTypeParamMiddleware(RequestDelegate next, string name,
string version, ApplicationConfiguration setup)
{
_setup = setup;
_next = next;
_name = name;
_version = version;
}
public async Task Invoke(HttpContext context)
{
Console.WriteLine($"In {nameof(DuplicateTypeParamMiddleware)} with" +
$"application name: '{_name}' and version: '{_version}'");
await _next(context);
}
}
As there are two string parameters
, the first string value supplied is assigned to the name parameter, and the second string value supplied is assigned to the version parameter:
// Correct
app.UseMiddleware<DuplicateTypeParamMiddleware>("MiddlewareParamDemo", "2");
// Incorrect
// app.UseMiddleware<DuplicateTypeParamMiddleware>("2", "MiddlewareParamDemo");
Notes
This functionality is especially useful in cases when a value determined at runtime (for example, application startup datetime) needs to be passed into middleware - having the ability to manually pass the value in instead of creating new entities to hold the values, and registering them with the dependency injection container, can save time and simplify code.
References
Inject dependency to your middleware class manually
Daily Drop 175: 05-10-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.