Middlewareaktivierung mit einem Drittanbietercontainer in ASP.NET CoreMiddleware activation with a third-party container in ASP.NET Core

In diesem Artikel wird veranschaulicht, wie IMiddlewareFactory und IMiddleware als Erweiterungspunkt für die Aktivierung von Middleware mit einem Drittanbietercontainer verwendet werden.This article demonstrates how to use IMiddlewareFactory and IMiddleware as an extensibility point for middleware activation with a third-party container. Einführende Informationen zu IMiddlewareFactory und IMiddleware finden Sie unter Factorybezogene Middlewareaktivierung in ASP.NET Core.For introductory information on IMiddlewareFactory and IMiddleware, see Factorybezogene Middlewareaktivierung in ASP.NET Core.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

Die Beispiel-App stellt die Aktivierung von Middleware durch eine IMiddlewareFactory-Implementierung (SimpleInjectorMiddlewareFactory) dar.The sample app demonstrates middleware activation by an IMiddlewareFactory implementation, SimpleInjectorMiddlewareFactory. Das Beispiel verwendet den Dependency Injection-Container Simple Injector.The sample uses the Simple Injector dependency injection (DI) container.

Die Middlewareimplementierungen in diesem Beispiel erfassen den Wert, der von einem Parameter für Abfragezeichenfolgen (key) angegeben wird.The sample's middleware implementation records the value provided by a query string parameter (key). Die Middleware verwendet einen eingefügten Datenbankkontext (einen bereichsbezogenen Dienst), um den Abfragezeichenwert in einer speicherinternen Datenbank zu erfassen.The middleware uses an injected database context (a scoped service) to record the query string value in an in-memory database.

Hinweis

Die Beispiel-App verwendet Simple Injector ausschließlich zu Demonstrationszwecken.The sample app uses Simple Injector purely for demonstration purposes. Die Verwendung von Simple Injector ist nicht verpflichtend.Use of Simple Injector isn't an endorsement. Die Ansätze für die Aktivierung von Middleware, die in der Dokumentation zu Simple Injector und in GitHub-Problemen beschrieben werden, werden von den Besitzern von Simple Injector empfohlen.Middleware activation approaches described in the Simple Injector documentation and GitHub issues are recommended by the maintainers of Simple Injector. Weitere Informationen finden Sie in der Dokumentation zu Simple Injector und im GitHub-Repository für Simple Injector.For more information, see the Simple Injector documentation and Simple Injector GitHub repository.

IMiddlewareFactoryIMiddlewareFactory

IMiddlewareFactory stellt Methoden zur Verfügung, um die Middleware zu erstellen.IMiddlewareFactory provides methods to create middleware.

In der Beispiel-App wird eine Middlewarefactory implementiert, um eine SimpleInjectorActivatedMiddleware-Instanz zu erstellen.In the sample app, a middleware factory is implemented to create an SimpleInjectorActivatedMiddleware instance. Die Middlewarefactory verwendet den Simple Injector-Container, um die Middleware aufzulösen:The middleware factory uses the Simple Injector container to resolve the 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.
    }
}

IMiddlewareIMiddleware

IMiddleware definiert Middleware für die Anforderungspipeline der App.IMiddleware defines middleware for the app's request pipeline.

Middleware, die von einer IMiddlewareFactory-Implementierung (Middleware/SimpleInjectorActivatedMiddleware.cs) aktiviert wurde:Middleware activated by an IMiddlewareFactory implementation (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);
    }
}

Eine Erweiterung (Middleware/MiddlewareExtensions.cs) wird für die Middleware erstellt:An extension is created for the middleware (Middleware/MiddlewareExtensions.cs):

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

Startup.ConfigureServices muss mehrere Tasks durchführen:Startup.ConfigureServices must perform several tasks:

  • Richten Sie den Simple Injector-Container ein.Set up the Simple Injector container.
  • Registrieren Sie die Factory und die Middleware.Register the factory and middleware.
  • Stellen Sie den Datenbankkontext der App über den Simple Injector-Container zur Verfügung.Make the app's database context available from the Simple Injector 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();
}

Die Middlewares wird in der Anforderungsverarbeitungspipeline in Startup.Configure registriert:The middleware is registered in the request processing pipeline in 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();
    });
}

In diesem Artikel wird veranschaulicht, wie IMiddlewareFactory und IMiddleware als Erweiterungspunkt für die Aktivierung von Middleware mit einem Drittanbietercontainer verwendet werden.This article demonstrates how to use IMiddlewareFactory and IMiddleware as an extensibility point for middleware activation with a third-party container. Einführende Informationen zu IMiddlewareFactory und IMiddleware finden Sie unter Factorybezogene Middlewareaktivierung in ASP.NET Core.For introductory information on IMiddlewareFactory and IMiddleware, see Factorybezogene Middlewareaktivierung in ASP.NET Core.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)View or download sample code (how to download)

Die Beispiel-App stellt die Aktivierung von Middleware durch eine IMiddlewareFactory-Implementierung (SimpleInjectorMiddlewareFactory) dar.The sample app demonstrates middleware activation by an IMiddlewareFactory implementation, SimpleInjectorMiddlewareFactory. Das Beispiel verwendet den Dependency Injection-Container Simple Injector.The sample uses the Simple Injector dependency injection (DI) container.

Die Middlewareimplementierungen in diesem Beispiel erfassen den Wert, der von einem Parameter für Abfragezeichenfolgen (key) angegeben wird.The sample's middleware implementation records the value provided by a query string parameter (key). Die Middleware verwendet einen eingefügten Datenbankkontext (einen bereichsbezogenen Dienst), um den Abfragezeichenwert in einer speicherinternen Datenbank zu erfassen.The middleware uses an injected database context (a scoped service) to record the query string value in an in-memory database.

Hinweis

Die Beispiel-App verwendet Simple Injector ausschließlich zu Demonstrationszwecken.The sample app uses Simple Injector purely for demonstration purposes. Die Verwendung von Simple Injector ist nicht verpflichtend.Use of Simple Injector isn't an endorsement. Die Ansätze für die Aktivierung von Middleware, die in der Dokumentation zu Simple Injector und in GitHub-Problemen beschrieben werden, werden von den Besitzern von Simple Injector empfohlen.Middleware activation approaches described in the Simple Injector documentation and GitHub issues are recommended by the maintainers of Simple Injector. Weitere Informationen finden Sie in der Dokumentation zu Simple Injector und im GitHub-Repository für Simple Injector.For more information, see the Simple Injector documentation and Simple Injector GitHub repository.

IMiddlewareFactoryIMiddlewareFactory

IMiddlewareFactory stellt Methoden zur Verfügung, um die Middleware zu erstellen.IMiddlewareFactory provides methods to create middleware.

In der Beispiel-App wird eine Middlewarefactory implementiert, um eine SimpleInjectorActivatedMiddleware-Instanz zu erstellen.In the sample app, a middleware factory is implemented to create an SimpleInjectorActivatedMiddleware instance. Die Middlewarefactory verwendet den Simple Injector-Container, um die Middleware aufzulösen:The middleware factory uses the Simple Injector container to resolve the 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.
    }
}

IMiddlewareIMiddleware

IMiddleware definiert Middleware für die Anforderungspipeline der App.IMiddleware defines middleware for the app's request pipeline.

Middleware, die von einer IMiddlewareFactory-Implementierung (Middleware/SimpleInjectorActivatedMiddleware.cs) aktiviert wurde:Middleware activated by an IMiddlewareFactory implementation (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);
    }
}

Eine Erweiterung (Middleware/MiddlewareExtensions.cs) wird für die Middleware erstellt:An extension is created for the middleware (Middleware/MiddlewareExtensions.cs):

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

Startup.ConfigureServices muss mehrere Tasks durchführen:Startup.ConfigureServices must perform several tasks:

  • Richten Sie den Simple Injector-Container ein.Set up the Simple Injector container.
  • Registrieren Sie die Factory und die Middleware.Register the factory and middleware.
  • Stellen Sie den Datenbankkontext der App über den Simple Injector-Container zur Verfügung.Make the app's database context available from the Simple Injector container.
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();
}

Die Middlewares wird in der Anforderungsverarbeitungspipeline in Startup.Configure registriert:The middleware is registered in the request processing pipeline in Startup.Configure:

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

    app.UseSimpleInjectorActivatedMiddleware();

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

Zusätzliche RessourcenAdditional resources