• ASP.NET Core 中基于工厂的中间件激活


    IMiddlewareFactory/IMiddleware 是中间件激活的扩展点。

    UseMiddleware 扩展方法检查中间件的已注册类型是否实现 IMiddleware。 如果是,则使用在容器中注册的 IMiddlewareFactory 实例来解析 IMiddleware 实现,而不使用基于约定的中间件激活逻辑。 中间件在应用的服务容器中注册为作用域或瞬态服务。

    优点:

    • 按客户端请求(作用域服务的注入)激活
    • 让中间件强类型化

    IMiddleware 按客户端请求(连接)激活,因此作用域服务可以注入到中间件的构造函数中。

    IMiddleware

    IMiddleware 定义应用的请求管道的中间件。 InvokeAsync(HttpContext, RequestDelegate) 方法处理请求,并返回代表中间件执行的 Task。

    使用约定激活的中间件:

    public class ConventionalMiddleware
    {
        private readonly RequestDelegate _next;
    
        public ConventionalMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task InvokeAsync(HttpContext context, AppDbContext db)
        {
            var keyValue = context.Request.Query["key"];
    
            if (!string.IsNullOrWhiteSpace(keyValue))
            {
                db.Add(new Request()
                    {
                        DT = DateTime.UtcNow, 
                        MiddlewareActivation = "ConventionalMiddleware", 
                        Value = keyValue
                    });
    
                await db.SaveChangesAsync();
            }
    
            await _next(context);
        }
    }

    使用 MiddlewareFactory 激活的中间件:

    public class FactoryActivatedMiddleware : IMiddleware
    {
        private readonly AppDbContext _db;
    
        public FactoryActivatedMiddleware(AppDbContext db)
        {
            _db = db;
        }
    
        public async Task InvokeAsync(HttpContext context, RequestDelegate next)
        {
            var keyValue = context.Request.Query["key"];
    
            if (!string.IsNullOrWhiteSpace(keyValue))
            {
                _db.Add(new Request()
                    {
                        DT = DateTime.UtcNow, 
                        MiddlewareActivation = "FactoryActivatedMiddleware", 
                        Value = keyValue
                    });
    
                await _db.SaveChangesAsync();
            }
    
            await next(context);
        }
    }

    程序会为中间件创建扩展:

    public static class MiddlewareExtensions
    {
        public static IApplicationBuilder UseConventionalMiddleware(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<ConventionalMiddleware>();
        }
    
        public static IApplicationBuilder UseFactoryActivatedMiddleware(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<FactoryActivatedMiddleware>();
        }
    }

    无法通过 UseMiddleware 将对象传递给工厂激活的中间件:

    public static IApplicationBuilder UseFactoryActivatedMiddleware(
        this IApplicationBuilder builder, bool option)
    {
        // Passing 'option' as an argument throws a NotSupportedException at runtime.
        return builder.UseMiddleware<FactoryActivatedMiddleware>(option);
    }

    将工厂激活的中间件添加到 Startup.ConfigureServices 的内置容器中:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<AppDbContext>(options =>
            options.UseInMemoryDatabase("InMemoryDb"));
    
        services.AddTransient<FactoryActivatedMiddleware>();
    
        services.AddRazorPages();
    }

    两个中间件均在 Startup.Configure 的请求处理管道中注册:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
        }
    
        app.UseConventionalMiddleware();
        app.UseFactoryActivatedMiddleware();
    
        app.UseStaticFiles();
        app.UseRouting();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }

    IMiddlewareFactory

    IMiddlewareFactory 提供中间件的创建方法。 中间件工厂实现在容器中注册为作用域服务。

    可在 Microsoft.AspNetCore.Http 包中找到默认的 IMiddlewareFactory 实现(即 MiddlewareFactory)。

  • 相关阅读:
    jq---方法总结
    Coderfroces 862 B . Mahmoud and Ehab and the bipartiteness
    Coin
    joisino's travel
    日天的终生大事(dp)
    Codefroces 852 G. Bathroom terminal
    Codefroces432 div2 A,B,C
    Atcoder ABC 069 C
    Codefroces 849 A,B
    HDU 6186 CS Course
  • 原文地址:https://www.cnblogs.com/yangzhili/p/13972314.html
Copyright © 2020-2023  润新知