在解析时使用模块特定的注册



我有一个应用程序,它使用两个不同的模块(实现为Autofac.Module(来注册它们提供的服务。每个都有一个适配器,用于通过不同方法生成相同数据的硬件设备。

public class AdapterA : IDataProducer {
public AdapterA(IConfigSource conf){
// do something with conf, like setting an IP address, port etc.
}
}
public ModuleA : Module{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AdapterA>().As<IDataProducer>();
// the config source is specific to Module A, as it contains details about the hardware
builder.Register(c => new IniConfigSource("moduleA.ini")).As<IConfigSource>();
}
}

现在,当我在主应用程序中注册该模块时,它运行良好,依赖关系也得到了正确解决。

builder.RegisterModule<ModuleA>();

在我的主应用程序中,我使用IConfigSource来读取/写入特定于应用程序的设置。当我用不同的设置文件在那里注册另一个IConfigSource时,问题就变得显而易见了。

protected override void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterModule<ModuleA>();
builder.Register(c => new IniConfigSource("mainprogram.ini")).As<IConfigSource>();
}

在Resolution时,第二次注册生效,并且我的ModuleA接收到错误的配置文件读取器。

四处寻找解决方案,我试图通过更改注册类型来解决这个问题,如下所示:

public interface IModuleAConfigSource : IConfigSource {}

builder.Register(c => new IniConfigSource("moduleA.ini")).As<IModuleAConfigSource>();

但这并不奏效。Autofac在解析时抱怨类型IniconfigSource无法分配给接口IModuleAConfigSource。在应用程序启动时,我在单个函数中使用带有注册的构造函数注入。

在这里什么是好的策略?我知道我可以使用具体的类型来解决这个问题,但有没有办法将注册模块保持在本地,即在解析类型以使用该模块的注册时?

经过更多的阅读,我认为键控服务注册对我来说是可行的。我用模块专用密钥注册IConfigSource,如下所示:

builder.Register(c => new IniConfigSource("moduleA.ini")).Keyed<IConfigSource>("moduleA");

以及取决于服务的类型为:

builder.RegisterType<ConcreteModuleAType>().AsSelf().WithAttributeFiltering();

ConcreteModuleAType的构造函数具有属性

public ConcreteModuleAType([KeyFilter("moduleA")] IConfigSource configSource)    {
this.configSource = configSource;
}

这对我来说是一个很好的解决方案。唯一的问题是模块注册的顺序很重要。模块必须最后注册,因为显然非键控注册会覆盖键控注册。

相关内容

  • 没有找到相关文章

最新更新