为什么 ASP.NET Core 中的中间件需要特定的语义,而不是接口?
Why middleware in ASP.NET Core requires specific semantics, but not an interface?
众所周知,ASP.NET Core 中方法 Configure (class Startup) 的 IApplicationBuilder 需要特定语义(方法 'Invoke' 的输入参数为 HttpContext 类型,任务为 return 值)。但是为什么它没有作为接口实现呢?我可以这样写:
public class FakeMiddleware
{
}
并注册:
app.UseMiddleware<FakeMiddleware>();
我们会得到一个运行时错误。当然,这是一件很简单的事情,很容易被发现和修复,但是实现起来很粗糙,没有界面?
Invoke 方法很灵活,您可以要求额外的参数。 ASP.NET 将使用应用程序的服务配置注入附加参数。
public async Task Invoke(HttpContext ctx,
IHostingEnvironment host,
ISomethingElse service)
{
// ...
}
C# 接口定义无法很好地提供这种灵活性。
Since 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);
}
}
除了app.UseMiddleware<InterfaceMiddleware>()
。您需要在 DI 中注册您的中间件(不需要单例生命周期)。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<InterfaceMiddlewareOptions>(opts =>
{
opts.Message = "IMiddleware interface is implemented";
});
services.AddSingleton<InterfaceMiddleware>();
}
众所周知,ASP.NET Core 中方法 Configure (class Startup) 的 IApplicationBuilder 需要特定语义(方法 'Invoke' 的输入参数为 HttpContext 类型,任务为 return 值)。但是为什么它没有作为接口实现呢?我可以这样写:
public class FakeMiddleware
{
}
并注册:
app.UseMiddleware<FakeMiddleware>();
我们会得到一个运行时错误。当然,这是一件很简单的事情,很容易被发现和修复,但是实现起来很粗糙,没有界面?
Invoke 方法很灵活,您可以要求额外的参数。 ASP.NET 将使用应用程序的服务配置注入附加参数。
public async Task Invoke(HttpContext ctx,
IHostingEnvironment host,
ISomethingElse service)
{
// ...
}
C# 接口定义无法很好地提供这种灵活性。
Since 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);
}
}
除了app.UseMiddleware<InterfaceMiddleware>()
。您需要在 DI 中注册您的中间件(不需要单例生命周期)。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<InterfaceMiddlewareOptions>(opts =>
{
opts.Message = "IMiddleware interface is implemented";
});
services.AddSingleton<InterfaceMiddleware>();
}