Ветвление конвейера с использованием методов MapWhen и UseWhen

В предыдущей части мы рассмотрели метод Map(), который также как и методы Run() и Use() используется для встраивания middleware в конвейер запросов ASP.NET и, при этом, создает ветвление конвейера. Сегодня рассмотрим ещё два метода ASP.NET Core для встраивания middleware и ветвления конвейера запросов — это методы MapWhen() и UseWhen().

Метод MapWhen

Метод MapWhen реализован как метод расширения IApplicationBuilder и имеет следующую сигнатуру:

IApplicationBuilder MapWhen(this IApplicationBuilder app, Func<HttpContext, bool> predicate, Action<IApplicationBuilder> configuration)

здесь

  • predicate — это делегат, который представляет собой некоторое условие. В качестве входного параметра принимает контекст запроса (HttpContext), а в качестве результата возвращает true, если условие оказывается истинно.
  • configuration — действие в котором производится работа с объектом типа IApplicationBuilder, то есть, по сути, настраивается новая ветка конвейера запросов ASP.NET

Рассмотрим работу этого метода на примере:

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        app.MapWhen(
                context=>context.Request.Path.StartsWithSegments("/page"),//условие - путь начинается с /page
                //работаем с IApplicationBuilder
                appBuilder =>
                {
                    //встраиваем первый middleware
                    appBuilder.Use(async (context, next) => 
                    {
                        //выводим текущее время
                        await context.Response.WriteAsync($"Время: {DateTime.Now} \r\n");
                        await next.Invoke();    
                    });
                    //страиваем второй middleware
                    appBuilder.Run(async context =>
                    {
                        await context.Response.WriteAsync($"Путь: {context.Request.Path}");
                    });
                }
             );


        app.Run(async context => await context.Response.WriteAsync("Index page"));

        app.Run();
    }
}

В качестве условия для создания новой ветки мы указали:

context=>context.Request.Path.StartsWithSegments("/page")

то есть, если запрашивается любая страница, путь которой начинается с /path, то условие будет истинным. Далее, мы создаем новую ветку конвейера запросов, в которую страиваем два компонента middleware:

appBuilder =>
{
    //встраиваем первый middleware
    appBuilder.Use(async (context, next) => 
    {
        //выводим текущее время
        await context.Response.WriteAsync($"Время: {DateTime.Now} \r\n");
        await next.Invoke();    
    });
    //страиваем второй middleware
    appBuilder.Run(async context =>
    {
        await context.Response.WriteAsync($"Путь: {context.Request.Path}");
    });
}

первый компонент выведет на страницу текущее время, а второй — путь. В запущенном приложении это может выглядеть следующим образом:

Для удобства, мы можем вынести проверку условия и действия по созданию ветки в отдельные методы. Например, так:

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();

    app.MapWhen(IsPage, CreateBranch);

    app.Run(async context => await context.Response.WriteAsync("Index page"));

    app.Run();

    //проверка условия
    static bool IsPage(HttpContext context)
    {
        return context.Request.Path.StartsWithSegments("/page");
    }

    void CreateBranch(IApplicationBuilder appBuilder)
    {
        //встраиваем первый middleware
        appBuilder.Use(async (context, next) =>
        {
            //выводим текущее время
            await context.Response.WriteAsync($"Время: {DateTime.Now} \r\n");
            await next.Invoke();
        });
        //страиваем второй middleware
        appBuilder.Run(async context =>
        {
            await context.Response.WriteAsync($"Путь: {context.Request.Path}");
        });
    }
}

Метод UseWhen

Метод UseWhen() во многом схож с MapWhen() и также принимает в качестве параметра делегат в котором проверяется некоторое условие. Основным отличием является то, что новая ветвь объединяется с основной веткой, если новая ветвь не содержит терминального middleware. Например, перепишем наш код следующим образом:

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        var app = builder.Build();

        //новая ветка теперь будет объединяться с основной
        app.UseWhen(IsPage, CreateBranch);

        app.Run(async context => await context.Response.WriteAsync("Index page"));

        app.Run();

        static bool IsPage(HttpContext context)
        {
            return context.Request.Path.StartsWithSegments("/page");
        }

        void CreateBranch(IApplicationBuilder appBuilder)
        {
            appBuilder.Use(async (context, next) =>
            {
                await context.Response.WriteAsync($"Время: {DateTime.Now} \r\n");
                await next.Invoke();
            });
            //убрали терминальный middleware 
            appBuilder.Use(async (context, next) =>
            {
                await context.Response.WriteAsync($"Путь: {context.Request.Path}\r\n");
                await next.Invoke();
            });
        }
    }
}

Теперь запустим приложение и получим следующий результат:

Так как в UseWhen() мы не использовали терминальный middleware, то новая ветка конвейера была объединена с основной.

Дополнительно стоит также напомнить, что, как и в случае с методом Map(), новые ветки конвейера создаются один раз.

Итого

Сегодня мы рассмотрели ещё два метода, позволяющих осуществить ветвление конвейера запросов — MapWhen() и UseWhen(). Оба этих метода работают практически идентично — на основании заданного условия создают новую ветку конвейера. При этом, ветка, создаваемая с использованием UseWhen() может объединяться с основной.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии