Bagikan melalui


Aktivasi middleware dengan kontainer pihak ketiga di ASP.NET Core

Artikel ini menunjukkan cara menggunakan IMiddlewareFactory dan IMiddleware sebagai titik ekstensibilitas untuk aktivasi middleware dengan kontainer pihak ketiga. Untuk informasi pengantar tentang IMiddlewareFactory dan IMiddleware, lihat Aktivasi middleware berbasis pabrik di ASP.NET Core.

Melihat atau mengunduh kode sampel (cara mengunduh)

Aplikasi sampel menunjukkan aktivasi middleware oleh IMiddlewareFactory implementasi, SimpleInjectorMiddlewareFactory. Sampel menggunakan kontainer injeksi dependensi Injektor Sederhana (DI).

Implementasi middleware sampel mencatat nilai yang disediakan oleh parameter string kueri (key). Middleware menggunakan konteks database yang disuntikkan (layanan terlingkup) untuk merekam nilai string kueri dalam database dalam memori.

Catatan

Aplikasi sampel menggunakan Simple Injector murni untuk tujuan demonstrasi. Penggunaan Simple Injector bukanlah dukungan. Pendekatan aktivasi middleware yang dijelaskan dalam dokumentasi Injektor Sederhana dan masalah GitHub direkomendasikan oleh pengurus Simple Injector. Untuk informasi selengkapnya, lihat dokumentasi Simple Injector dan repositori GitHub Simple Injector.

IMiddlewareFactory

IMiddlewareFactory menyediakan metode untuk membuat middleware.

Di aplikasi sampel, pabrik middleware diimplementasikan untuk membuat SimpleInjectorActivatedMiddleware instans. Pabrik middleware menggunakan kontainer Simple Injector untuk mengatasi middleware:

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 menentukan middleware untuk alur permintaan aplikasi.

Middleware diaktifkan oleh IMiddlewareFactory implementasi (Middleware/SimpleInjectorActivatedMiddleware.cs):

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

Ekstensi dibuat untuk middleware (Middleware/MiddlewareExtensions.cs):

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

Startup.ConfigureServices harus melakukan beberapa tugas:

  • Siapkan kontainer Simple Injector.
  • Daftarkan pabrik dan middleware.
  • Buat konteks database aplikasi tersedia dari kontainer Simple Injector.
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 terdaftar dalam alur pemrosesan permintaan di Startup.Configure:

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

Artikel ini menunjukkan cara menggunakan IMiddlewareFactory dan IMiddleware sebagai titik ekstensibilitas untuk aktivasi middleware dengan kontainer pihak ketiga. Untuk informasi pengantar tentang IMiddlewareFactory dan IMiddleware, lihat Aktivasi middleware berbasis pabrik di ASP.NET Core.

Melihat atau mengunduh kode sampel (cara mengunduh)

Aplikasi sampel menunjukkan aktivasi middleware oleh IMiddlewareFactory implementasi, SimpleInjectorMiddlewareFactory. Sampel menggunakan kontainer injeksi dependensi Injektor Sederhana (DI).

Implementasi middleware sampel mencatat nilai yang disediakan oleh parameter string kueri (key). Middleware menggunakan konteks database yang disuntikkan (layanan terlingkup) untuk merekam nilai string kueri dalam database dalam memori.

Catatan

Aplikasi sampel menggunakan Simple Injector murni untuk tujuan demonstrasi. Penggunaan Simple Injector bukanlah dukungan. Pendekatan aktivasi middleware yang dijelaskan dalam dokumentasi Injektor Sederhana dan masalah GitHub direkomendasikan oleh pengurus Simple Injector. Untuk informasi selengkapnya, lihat dokumentasi Simple Injector dan repositori GitHub Simple Injector.

IMiddlewareFactory

IMiddlewareFactory menyediakan metode untuk membuat middleware.

Di aplikasi sampel, pabrik middleware diimplementasikan untuk membuat SimpleInjectorActivatedMiddleware instans. Pabrik middleware menggunakan kontainer Simple Injector untuk mengatasi middleware:

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 menentukan middleware untuk alur permintaan aplikasi.

Middleware diaktifkan oleh IMiddlewareFactory implementasi (Middleware/SimpleInjectorActivatedMiddleware.cs):

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

Ekstensi dibuat untuk middleware (Middleware/MiddlewareExtensions.cs):

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

Startup.ConfigureServices harus melakukan beberapa tugas:

  • Siapkan kontainer Simple Injector.
  • Daftarkan pabrik dan middleware.
  • Buat konteks database aplikasi tersedia dari kontainer Simple Injector.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    // 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 terdaftar dalam alur pemrosesan permintaan di Startup.Configure:

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

    app.UseSimpleInjectorActivatedMiddleware();

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

Sumber Daya Tambahan: