代码之家  ›  专栏  ›  技术社区  ›  user3021830

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

  •  0
  • user3021830  · 技术社区  · 4 年前

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

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

    我有以下类作为初始数据

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

    我为依赖项注入创建了以下类

    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类实例化的对象,并在 Invoke(HttpContext context) 方法。

    到目前为止,我已经发现了一些以不同方式使用依赖注入的例子,例如将对象(从类a)传递给中间件的构造函数,但我希望在编写对象时读取其值设置的对象。

    0 回复  |  直到 4 年前
        1
  •  2
  •   David McEleney    4 年前

    由于您已注册的实例 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);
    }
    
        2
  •  2
  •   Peter Csala Matheus Robert Lichtnow    4 年前

    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)
    
    推荐文章