Why middleware in ASP.NET Core requires specific semantics, but not an interface?
Asked Answered
V

2

46

As known, IApplicationBuilder of the method Configure (class Startup) in ASP.NET Core requires specific semantics (to have method 'Invoke' with input parameter of HttpContext type and Task as return value). But why it's not implemented as interface? I can write something like it:

public class FakeMiddleware
{

}

and register it:

    app.UseMiddleware<FakeMiddleware>();

and we'll get an runtime error. Of course, it's trivial thing and easy to be found and fix, but it's implemented so rough, without interface?

Variometer answered 30/11, 2016 at 20:40 Comment(3)
Actually now there is an IMiddlewareStateless
@Stateless if I implement that interface, app will not even launch.Excisable
They like code that isn't self-documented.Marquetry
H
40

The Invoke method is flexible and you can ask for additional parameters. ASP.NET will inject the additional parameters using the application's service configuration.

public async Task Invoke(HttpContext ctx, 
                         IHostingEnvironment host,
                         ISomethingElse service)
{
    // ...
}

C# interface definitions can't provide this flexibility in a nice way.

Hexameter answered 30/11, 2016 at 21:18 Comment(4)
so, with DI we can think about disadvantages interfaces in current "version"? :) Because this situation (with additional parameters and resolving it automatically) can be more distributed than this placeVariometer
Oh gosh, that should be constructor injected. If it's a per-request dependency then a factory pattern would work nicelyDissyllable
Using a factory pattern would mean creating a factory for each transient type you would inject and make an explicit call to someFactory.Create() method. Doing so would probably make your code less adhering to the KISS principle. But that's maybe just a matter of taste ?Appulse
But, if the idea is to inject any service, wouldn't be easier to inject the IServiceProvider instead? Then a interface would be possible.Makeyevka
P
7

Since AspNetCore2.0 you can set middleware which implements interface IMiddleware.

public class InterfaceMiddleware : IMiddleware
{
    private InterfaceMiddlewareOptions _opts;

    public InterfaceMiddleware(IOptions<InterfaceMiddlewareOptions> opts)
    {
        _opts = opts.Value;
    }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        await context.Response.WriteAsync(_opts.Message);
    }
}

In addition to app.UseMiddleware<InterfaceMiddleware>(). You need to register your middleware in DI(singleton lifetime is not required).

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<InterfaceMiddlewareOptions>(opts =>
    {
        opts.Message = "IMiddleware interface is implemented";
    });

    services.AddSingleton<InterfaceMiddleware>();
}
Pericope answered 4/11, 2020 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.