从自定义中间件访问 ConfigureServices 中注入的参数

Accessing the parameters injected in ConfigureServices from custom Middleware

我正在练习学习更多关于 ASP.NET Core 中的依赖注入和中间件的知识,我遇到了一个我无法解决的问题,因此需要 Whosebug 其他成员的帮助。

在我的项目中,我试图创建一个中间件,它将一些初始数据与运行时收集的另一个数据结合起来。

我有以下class作为初始数据

public class A
{
    public string Name { get; set; }
    public string Description { get; set; }
}

我为依赖注入创建了以下class

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MiddlewareInitialDataExtension
    {
        public static IServiceCollection AddInitialData(this IServiceCollection services, Action<A> data)
        {
            A a = new A();
            data(a);
            return services.AddSingleton<A>(a);
        }    
    }
}

Startup.cs 文件中,我将其注入如下:

public void ConfigureServices(IServiceCollection services)
{
    services.AddInitialData(d =>
    {
        d.Name = "Some name";
        d.Description = "Some description";
    });
}

我也写了我的中间件如下:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

    public MyMiddleware(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await this._next(context);
    }
}

并在 Starup.cs 文件中注册了我的中间件,如下所示:

public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
    app.UseMiddleware(typeof(MyMiddleware));
}

此时我需要访问从 A class 实例化并在调用 Invoke(HttpContext context) 方法时注入应用程序的对象。

到目前为止,我已经找到了一些以不同方式使用依赖注入的示例,例如将对象(从 class A)传递给中间件的构造函数,但我想用它来读取对象按照写入的方式设置值。

当你在启动时注册了 A 的实例,你可以将它添加到中间件构造函数的签名中:

private readonly A _a;

public MyMiddleware(RequestDelegate next, A instanceOfA)
{
  _a = instanceOfA;
}

public async Task Invoke(HttpContext context)
{
    Console.WriteLine(_a.Name); // should print "Some name"
    await this._next(context);
}

can pass whatever parameter 您喜欢 Invoke 方法,DI 将负责注入。第一个参数应该是 HttpContext.

public MyMiddleware(RequestDelegate next)
public async Task InvokeAsync(HttpContext context, A theA)

如果你想在构造函数中传递参数,那么你必须使用Factory-based middleware

public MyMiddleware(A theA)
public async Task InvokeAsync(HttpContext context, RequestDelegate next)