0

我有一个应用程序,它使用两个不同的模块(实现为 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>();
    }

在解决时,第二次注册生效,我ModuleA收到了错误的配置文件阅读器。

环顾四周寻找解决方案,我尝试通过更改注册类型来解决此问题,如下所示:

public interface IModuleAConfigSource : IConfigSource {}

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

但这不起作用。Autofac 在解决时抱怨该类型IniconfigSource不可分配给接口 IModuleAConfigSource。我在应用程序启动时在单个函数中使用构造函数注入和注册。

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

4

1 回答 1

0

经过更多阅读,我认为键控服务注册对我有用。我IConfigSource使用模块特定的密钥注册我的,如下所示:

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

以及取决于服务的类型:

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

then的构造函数ConcreteModuleAType具有属性

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

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

于 2022-01-23T09:22:34.870 回答