【问题标题】:Using a combination of MapWhen and ApplicationBuilder in .net core app startup?在 .net 核心应用程序启动中使用 MapWhen 和 ApplicationBuilder 的组合?
【发布时间】:2019-03-12 23:02:58
【问题描述】:

是否可以部分分支启动?

作为一个例子,是否有可能有类似的东西:

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

【问题讨论】:

    标签: c# asp.net-core middleware startup


    【解决方案1】:

    简答

    是的。它将按您的预期工作。


    其实我们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 之前调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 2023-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多