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

Autofac注册同一类多实例时参数值共享,如何解决?

问题原因与解决方案

问题原因

你遇到的问题是因为Autofac注册时,两次调用As<IPreferencesRetriever>()会导致第二个注册覆盖第一个的默认IPreferencesRetriever服务。虽然你添加了Keyed标识,但每个注册同时被标记为默认服务,Autofac会将最后一次注册的实例作为默认实现,进而导致即使通过KeyFilter解析,也会出现实例混淆的情况;另外也可能是构造函数参数匹配失败,回退到了默认服务实例。

解决方案

1. 修改Autofac注册方式,移除默认服务注册

去掉As<IPreferencesRetriever>(),仅保留Keyed标识,确保两个单例实例完全独立,仅通过Key来解析:

using Autofac;
using Autofac.Extensions.DependencyInjection;

public void ConfigureContainer(ContainerBuilder builder)
{
    // Preferences
    builder.RegisterType<PreferencesRetriever>()
           .Keyed<IPreferencesRetriever>("PreferencesRetriever")
           .SingleInstance()
           .WithParameter("collection", _configureMongo(_mongoUrl, MONGODB_PREFERENCES_COLLECTION));

    // System Preferences
    builder.RegisterType<PreferencesRetriever>()
           .Keyed<IPreferencesRetriever>("SystemPreferencesRetriever")
           .SingleInstance()
           .WithParameter("collection", _configureMongo(_mongoUrl, MONGODB_SYSTEM_PREFERENCES_COLLECTION));
}

2. 验证构造函数参数匹配

确保PreferencesRetriever的构造函数中,集合参数的名称确实是collection。如果参数名称不同(例如mongoCollection),WithParameter("collection", ...)会匹配失败,导致注入默认服务实例。如果参数名称不匹配,改用按类型匹配:

.WithParameter(new TypedParameter(typeof(IMongoCollection<YourPreferenceType>), _configureMongo(_mongoUrl, MONGODB_PREFERENCES_COLLECTION)))

3. 确认_configureMongo返回独立实例

检查_configureMongo方法,确保传入不同集合名称时返回不同的IMongoCollection实例。可以在注册时添加日志输出集合名称,验证两次调用的结果:

var prefCollection = _configureMongo(_mongoUrl, MONGODB_PREFERENCES_COLLECTION);
Console.WriteLine($"Preferences collection: {prefCollection.CollectionNamespace.CollectionName}");

var systemPrefCollection = _configureMongo(_mongoUrl, MONGODB_SYSTEM_PREFERENCES_COLLECTION);
Console.WriteLine($"System Preferences collection: {systemPrefCollection.CollectionNamespace.CollectionName}");

4. 修复控制器日志类型(非核心但建议)

SystemPreferencesController中的ILogger泛型参数错误,应该对应自身控制器类型:

public SystemPreferencesController(
    [KeyFilter("SystemPreferencesRetriever")] IPreferencesRetriever preferencesRetriever,
    ILogger<SystemPreferencesController> logger) // 改为SystemPreferencesController
{
    _preferencesRetriever = preferencesRetriever;
    _logger = logger;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:52:57