You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在中间件、控制器与后台服务间共享Singleton实例?

嘿,我来帮你搞定这个问题!你已经成功注册了ConcurrentQueue<string>的单例服务,要在中间件里访问它其实有两种很实用的方式,下面我给你详细说明:

方法1:自定义中间件类通过构造函数注入

这种方式适合逻辑相对复杂的中间件,也是比较规范的做法。你可以创建一个自定义中间件类,直接在构造函数里注入ConcurrentQueue<string>实例:

public class DataWritingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ConcurrentQueue<string> _sharedQueue;

    // 构造函数注入已注册的ConcurrentQueue单例
    public DataWritingMiddleware(RequestDelegate next, ConcurrentQueue<string> sharedQueue)
    {
        _next = next;
        _sharedQueue = sharedQueue;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 在这里就可以直接操作队列写入数据了
        _sharedQueue.Enqueue($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 中间件写入的数据");

        // 别忘了调用后续中间件,保证请求管道正常流转
        await _next(context);
    }
}

之后在Program.cs(或者Startup.cs的Configure方法)里注册这个中间件就行:

app.UseMiddleware<DataWritingMiddleware>();
方法2:内联中间件通过RequestServices获取

如果你的中间件逻辑很简单,不想单独写一个类,也可以直接在app.Use()里通过HttpContext的请求服务来获取单例:

app.Use(async (context, next) =>
{
    // 从RequestServices中获取已注册的ConcurrentQueue实例
    var sharedQueue = context.RequestServices.GetService<ConcurrentQueue<string>>();
    if (sharedQueue != null)
    {
        sharedQueue.Enqueue($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 内联中间件写入的数据");
    }

    // 继续执行后续请求管道
    await next();
});
补充说明
  • 你之前注册单例的代码是没问题的,再确认下:
    ConcurrentQueue<string> sharedData = new ConcurrentQueue<string>();
    services.AddSingleton(typeof(ConcurrentQueue<string>), sharedData);
    
  • 因为ConcurrentQueue本身是线程安全的,所以不管是中间件、控制器还是后台服务,并发读写都不用额外加锁,放心用就行。

内容的提问来源于stack exchange,提问作者Sandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:20:04