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는 미들웨어를 만드는 메서드를 제공합니다. 미들웨어 팩터리 구현은 범위가 지정된 서비스로 컨테이너에 등록됩니다.

기본 IMiddlewareFactory 구현인 MiddlewareFactoryMicrosoft.AspNetCore.Http 패키지에 있습니다.

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.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

두 미들웨어는 모두 Startup.Configure의 요청 처리 파이프라인에 등록됩니다.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseConventionalMiddleware();
    app.UseFactoryActivatedMiddleware();

    app.UseStaticFiles();
    app.UseMvc();
}

IMiddlewareFactory

IMiddlewareFactory는 미들웨어를 만드는 메서드를 제공합니다. 미들웨어 팩터리 구현은 범위가 지정된 서비스로 컨테이너에 등록됩니다.

기본 IMiddlewareFactory 구현인 MiddlewareFactoryMicrosoft.AspNetCore.Http 패키지에 있습니다.

추가 자료