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

Autofac RegisterInstance未按预期工作:注入的IMemoryCache实例不一致

IMemoryCache实例注入不一致问题

在我的ASP.NET Core应用中,我在Startup里以实例形式注册了IMemoryCache,但注入控制器时,收到的却是和注册时不同的实例,明明注册的是单例实例,这是怎么回事?


Program.cs代码

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args)
            .Build()
            .Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureServices(s => s.AddAutofac())
            .UseStartup<Startup>();
}

Startup.cs代码

public class Startup
{
    public static IMemoryCache MemoryCacheInstance;

    public Startup()
    {
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        MemoryCacheInstance = new MemoryCache(new MemoryCacheOptions());

        var builder = new ContainerBuilder();
        builder.RegisterInstance<IMemoryCache>(MemoryCacheInstance);
        builder.Populate(services);

        return new AutofacServiceProvider(builder.Build());
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

}

Controller代码

public class UtilsController : Controller
{
    public UtilsController(IMemoryCache memoryCache)
    {
        if (Startup.MemoryCacheInstance == memoryCache)
        {
            // 调试器永远不会走到这里
        }
    }

    [HttpGet("api/utils/test-method")]
    public string TestMethod()
    {
        return null;
    }
}

问题原因

核心问题是**services.AddMvc()会自动注册IMemoryCache的默认实现**,而你调用builder.Populate(services)时,把这个默认注册也同步到了Autofac容器中。Autofac解析服务时,默认注册的优先级高于你手动调用的RegisterInstance,最终导致控制器注入的是框架自动创建的实例,而非你手动初始化的那个。

解决方法

有三种可行的修复方式:

  1. 调整注册顺序,先加自定义实例再调用AddMvc
    框架的AddMvc()会检测服务集合中是否已存在IMemoryCache注册,若存在则不会重复添加。所以先注册你的实例,再添加Mvc服务即可:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        // 先注册自定义IMemoryCache实例
        MemoryCacheInstance = new MemoryCache(new MemoryCacheOptions());
        services.AddSingleton<IMemoryCache>(MemoryCacheInstance);
    
        // 再添加Mvc服务
        services.AddMvc();
    
        var builder = new ContainerBuilder();
        builder.Populate(services);
    
        return new AutofacServiceProvider(builder.Build());
    }
    
  2. 移除默认注册后再添加自定义实例
    如果不想调整顺序,可以先移除服务集合中已有的IMemoryCache注册,再添加自己的实例:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        MemoryCacheInstance = new MemoryCache(new MemoryCacheOptions());
        // 移除框架自动注册的IMemoryCache
        var cacheDescriptor = services.FirstOrDefault(d => d.ServiceType == typeof(IMemoryCache));
        if (cacheDescriptor != null)
        {
            services.Remove(cacheDescriptor);
        }
        // 添加自定义实例
        services.AddSingleton<IMemoryCache>(MemoryCacheInstance);
    
        var builder = new ContainerBuilder();
        builder.Populate(services);
    
        return new AutofacServiceProvider(builder.Build());
    }
    
  3. 在Autofac Populate后覆盖注册
    若坚持使用Autofac的RegisterInstance,可以在builder.Populate(services)之后再注册实例,这样会覆盖之前从服务集合同步过来的默认注册:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        MemoryCacheInstance = new MemoryCache(new MemoryCacheOptions());
    
        var builder = new ContainerBuilder();
        builder.Populate(services);
        // 覆盖默认注册
        builder.RegisterInstance<IMemoryCache>(MemoryCacheInstance).SingleInstance();
    
        return new AutofacServiceProvider(builder.Build());
    }
    

以上任意一种方式,都能确保控制器注入的是你手动创建的IMemoryCache实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:20:33