部分分支启动是否可能?
举个例子,是否可能有类似的东西:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.AlwaysUseThisMiddleware();
app.MapWhen(conditionA, appBuilder => {appBuilder.SometimesUseThisOne;})
app.MapWhen(conditionB, appBuilder => {appBuilder.SometimesUseThisOtherOne;})
或者我需要将AlwaysUseThisMiddleware
放在每个分支内吗?像这样:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.MapWhen(conditionA, appBuilder =>
{
appBuilder.AlwaysUseThisMiddleware(); // Duplicated
appBuilder.SometimesUseThisOne;
)
app.MapWhen(conditionB, appBuilder =>
{
appBuilder.AlwaysUseThisMiddleware(); // Duplicated
appBuilder.SometimesUseThisOtherOne;
)
简答:
是。它会像你期望的那样工作。
实际上,当我们Use()
一系列中间件时,我们正在注册一系列中间件,这些中间件将在处理请求时按顺序调用。
MapWhen()
方法只不过是辅助方法that invokes the Use()
。 MapWhen(predicate,configFn)
做的是注册运行as below的东西:
if (predicate(context)){
await branch(context);
} else {
await _next(context);
}
因此,当我们调用MapWhen()
时,我们正在注册另一个分支处理的中间件。
例如 :
app.UseMiddleware<AlwaysUseThisMiddleware>();
app.MapWhen(ctx=>ctx.Request.Query["a"]=="1", appBuilder =>{
appBuilder.UseMiddleware<SometimesUseThisOne>();
});
app.MapWhen(ctx=>ctx.Request.Query["b"]=="1", appBuilder =>{
appBuilder.UseMiddleware<SometimesUseThisOtherOne>();
})
// ...
基本上,此代码以下列方式运行:
call `AlwaysUseThisMiddleware`;
////////////////////////////////////
if (ctx.Request.Query["a"]=="1"){
call SometimesUseThisOne ;
} else {
//------------------------------------------
if (ctx.Request.Query["b"]=="1"){
call SometimesUseThisOtherOne ;
} else {
//##################################################
await _next(context); // call other middlewares ...
//##################################################
}
//-----------------------------------------
}
////////////////////////////////////
或者,如果您愿意,也可以按如下方式重写:
call `AlwaysUseThisMiddleware` middleware
if(ctx.Request.Query["a"]=="1") // go to branch 1
call `SometimesUseThisOne` middleware
else if (ctx.Request.Query["b"]=="1") // go to branch 2
call `SometimesUseThisOtherOne` middleware
else :
...
请注意,这里的分支被翻译为else if
而不是if
。并且中间件AlwaysUseThisMiddleware
总是在branch1和branch2之前调用。