为什么ASP.NET Core中的中间件需要特定的语义,而不是接口?

Ole*_* Sh 29 middleware interface owin owin-middleware asp.net-core

众所周知,ASP.NET Core中方法Configure(类Startup)的IApplicationBuilder需要特定的语义(使用HttpContext类型的输入参数和作为返回值的Task的方法'Invoke').但为什么它没有作为接口实现?我可以写类似的东西:

public class FakeMiddleware
{

}
Run Code Online (Sandbox Code Playgroud)

并注册:

    app.UseMiddleware<FakeMiddleware>();
Run Code Online (Sandbox Code Playgroud)

我们会得到一个运行时错误.当然,它是微不足道的东西,易于找到和修复,但它实现如此粗糙,没有界面?

Ode*_*ode 25

Invoke方法非常灵活,您可以要求其他参数.ASP.NET将使用应用程序的服务配置注入其他参数.

public async Task Invoke(HttpContext ctx, 
                         IHostingEnvironment host,
                         ISomethingElse service)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

C#接口定义无法以一种很好的方式提供这种灵活性.

  • 哦,天哪,应该是构造函数注入.如果它是按请求依赖,则工厂模式可以很好地工作 (9认同)

小智 6

从AspNetCore2.0开始, 您可以设置实现接口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);
    }
}
Run Code Online (Sandbox Code Playgroud)

此外app.UseMiddleware<InterfaceMiddleware>()。您需要在 DI 中注册您的中间件(不需要单例生命周期)。

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

    services.AddSingleton<InterfaceMiddleware>();
}
Run Code Online (Sandbox Code Playgroud)