Используете комбинацию MapWhen и ApplicationBuilder при запуске основного приложения .net? - PullRequest
1 голос
/ 13 марта 2019

Можно ли частично запустить ветвление?

Например, возможно ли что-то вроде:

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;
    )

1 Ответ

0 голосов
/ 13 марта 2019

Короткий ответ :

Да.Это будет работать, как вы ожидали.


На самом деле, когда мы Use() запускаем серию промежуточных программ, мы регистрируем серию промежуточных программ, которые будут последовательно вызываться при обработке запросов.

Метод MapWhen() является не более чем вспомогательным методом , который вызывает Use().Что делает MapWhen(predicate,configFn), так это регистрирует что-то, что работает , как показано ниже :

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.

...