Manually passing parameters to a middleware component

Using manually supplied parameters in conjunction with injected parameters

Home DailyDrop

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.
c# .net middleware parameters