Nguon: Microsoft Learn · .NET 8.0

Kích hoạt Middleware với Container Bên Thứ Ba trong ASP.NET Core

Nguồn: Middleware activation with a third-party container in ASP.NET Core

Bài viết này trình bày cách sử dụng IMiddlewareFactoryIMiddleware như một điểm mở rộng cho việc kích hoạt middleware (phần mềm trung gian) với container bên thứ ba. Để biết thông tin cơ bản về IMiddlewareFactoryIMiddleware, xem Kích hoạt Middleware dựa trên Factory trong ASP.NET Core.

Ứng dụng mẫu minh họa việc kích hoạt middleware bởi một cài đặt IMiddlewareFactory, SimpleInjectorMiddlewareFactory. Mẫu sử dụng container dependency injection (DI - tiêm phụ thuộc) Simple Injector.

Cài đặt middleware của mẫu ghi lại giá trị được cung cấp bởi một tham số query string (key). Middleware sử dụng một database context được tiêm vào (một service scoped) để ghi lại giá trị query string vào cơ sở dữ liệu in-memory.

Ứng dụng mẫu sử dụng Simple Injector chỉ cho mục đích minh họa. Việc sử dụng Simple Injector không phải là sự chứng thực. Các cách tiếp cận kích hoạt middleware được mô tả trong tài liệu và các vấn đề GitHub của Simple Injector được khuyến nghị bởi những người duy trì Simple Injector.

IMiddlewareFactory

IMiddlewareFactory cung cấp các phương thức để tạo middleware.

Trong ứng dụng mẫu, một middleware factory được cài đặt để tạo một instance SimpleInjectorActivatedMiddleware. Middleware factory sử dụng container Simple Injector để resolve middleware:

csharp
public class SimpleInjectorMiddlewareFactory : IMiddlewareFactory
{
    private readonly Container _container;

    public SimpleInjectorMiddlewareFactory(Container container)
    {
        _container = container;
    }

    public IMiddleware Create(Type middlewareType)
    {
        return _container.GetInstance(middlewareType) as IMiddleware;
    }

    public void Release(IMiddleware middleware)
    {
        // The container is responsible for releasing resources.
    }
}

IMiddleware

IMiddleware định nghĩa middleware cho request pipeline của ứng dụng.

Middleware được kích hoạt bởi một cài đặt IMiddlewareFactory (Middleware/SimpleInjectorActivatedMiddleware.cs):

csharp
public class SimpleInjectorActivatedMiddleware : IMiddleware
{
    private readonly AppDbContext _db;

    public SimpleInjectorActivatedMiddleware(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 = "SimpleInjectorActivatedMiddleware", 
                    Value = keyValue
                });

            await _db.SaveChangesAsync();
        }

        await next(context);
    }
}

Một extension được tạo cho middleware (Middleware/MiddlewareExtensions.cs):

csharp
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseSimpleInjectorActivatedMiddleware(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<SimpleInjectorActivatedMiddleware>();
    }
}

Startup.ConfigureServices phải thực hiện một số tác vụ:

csharp
private Container _container = new Container();

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    // Replace the default middleware factory with the 
    // SimpleInjectorMiddlewareFactory.
    services.AddTransient<IMiddlewareFactory>(_ =>
    {
        return new SimpleInjectorMiddlewareFactory(_container);
    });

    // Wrap ASP.NET Core requests in a Simple Injector execution 
    // context.
    services.UseSimpleInjectorAspNetRequestScoping(_container);

    // Provide the database context from the Simple 
    // Injector container whenever it's requested from 
    // the default service container.
    services.AddScoped<AppDbContext>(provider => 
        _container.GetInstance<AppDbContext>());

    _container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

    _container.Register<AppDbContext>(() => 
    {
        var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
        optionsBuilder.UseInMemoryDatabase("InMemoryDb");
        return new AppDbContext(optionsBuilder.Options);
    }, Lifestyle.Scoped);

    _container.Register<SimpleInjectorActivatedMiddleware>();

    _container.Verify();
}

Middleware được đăng ký trong request processing pipeline trong Startup.Configure:

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

    app.UseSimpleInjectorActivatedMiddleware();

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Tài nguyên bổ sung