C#中Autofac多模块下Configuration对象列表合并问题
在Autofac多模块中共享并修改单例Configuration对象的可行方案
你注册的Configuration是SingleInstance(单例),所以整个Autofac容器中只会存在这一个实例,只要修改该实例的Types列表,Module1和Module2中使用的都是同一个对象,自然能同步新增类型。以下是几种可靠的实现方式:
方案一:利用容器构建回调修改实例
在Module2中通过RegisterBuildCallback,在容器完全构建完成后获取已实例化的Configuration对象并添加新类型,这是最稳妥的方式,避免容器构建过程中的依赖问题:
public class Module2 : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterBuildCallback(context => { // 获取Module1注册的单例Configuration实例 var config = context.ResolveKeyed<Configuration>("Object1"); // 添加Module2需要的新类型 config.Types.Add(context.ResolveKeyed<Type>("Type3")); config.Types.Add(context.ResolveKeyed<Type>("Type4")); }); } }
方案二:通过扩展点模式拆分配置逻辑
如果希望模块间解耦,避免直接修改实例,可以将Configuration的类型注册拆分为多个Action<Configuration>扩展点,由Module1统一执行:
Module1中的注册逻辑:
builder.Register(context => { var config = new Configuration("https://+:20303", null, "/temp", true, true); config.AutofacContext = context; // 执行所有模块注册的配置动作 var configActions = context.Resolve<IEnumerable<Action<Configuration>>>(); foreach (var action in configActions) { action(config); } return config; }) .Keyed<Configuration>("Object1") .SingleInstance(); // 注册Module1的类型添加动作 builder.Register<Action<Configuration>>(context => config => { config.Types.Add(context.ResolveKeyed<Type>("Type1")); config.Types.Add(context.ResolveKeyed<Type>("Type2")); });
Module2中的注册逻辑:
public class Module2 : Module { protected override void Load(ContainerBuilder builder) { // 注册Module2的类型添加动作 builder.Register<Action<Configuration>>(context => config => { config.Types.Add(context.ResolveKeyed<Type>("Type3")); config.Types.Add(context.ResolveKeyed<Type>("Type4")); }); } }
关键说明
- 你提到的Autofac“覆盖同属性对象”是指重复注册同Key/同类型的组件会覆盖之前的注册,但这里我们并没有重新注册
Keyed<Configuration>("Object1"),而是修改已存在的单例实例,因此不存在覆盖问题。 - 单例实例的特性保证了所有模块获取的都是同一个对象,修改其
Types列表会全局生效。
内容的提问来源于stack exchange,提问作者Apuna12
相关产品推荐
相关产品推荐

