如何解决通过 Autofac 模块注册获取一个对象的多个实例
我有一个用例,我需要从 Autofac 模块中获取两个已注册对象的副本,并将它们传递给不同的类型。
在下面的代码示例中,
- 我想通过配置
dbConfig
传递 DataProtectionService 的对象来注册MyDbRepo
。 - 同样,我想传递一个带有配置
cacheConfig
的 DataProtectionService 对象来注册MyCacheRepo
。
但是,我不知道该怎么做?我在这里错过了一些非常基本的东西吗?
我没有删除此 DataProtectionServiceModule
的选项。有没有办法实现我的期望?
public class DataProtectionServiceModule : Module
{
private readonly string config;
public DataProtectionServiceModule(string config)
{
this.config = config;
}
protected override void Load(ContainerBuilder builder)
{
builder.Register<Token>(compContext =>
{ // a complex logic here
}).OnRelease(instance => instance.dispose());
builder.Register(c =>
{
// a logic to generate an object of IDataProtectionService
// this logic involves the use of config field of this class.
}).As<IDataProtectionService>();
}
}
public class MyDbRepo : IMyDbRepo
{
IDataProtectionService dataProtectionService;
public MyDbRepo(IDataProtectionService dataProtectionService)
{
this.dataProtectionService = dataProtectionService;
}
}
public class MyCacheRepo : IMyCacheRepo
{
IDataProtectionService dataProtectionService;
public MyCacheRepo(IDataProtectionService dataProtectionService)
{
this.dataProtectionService = dataProtectionService;
}
}
// Program.cs of my backend micro service
var builder = new ContainerBuilder();
builder.RegisterModule(new DataProtectionServiceModule("dbConfig"));
builder.RegisterModule(new DataProtectionServiceModule("cacheConfig")); // I have figured,this is wrong.
builder.RegisterType<MyDbRepo>().As<IMyDbRepo>().SingleInstance();
builder.RegisterType<MyCacheRepo>().As<IMyCacheRepo>().SingleInstance();
解决方法
您可以使用 Keyed Services。然后在您的注册中添加一个特定的 Resolve
。
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
// Program.cs of my backend micro service
var builder = new ContainerBuilder();
builder.RegisterModule(new DataProtectionServiceModule("dbConfig",DeviceState.Db));
builder.RegisterModule(new DataProtectionServiceModule("cacheConfig",DeviceState.Cache)); // I have figured,this is wrong.
builder.RegisterType<MyDbRepo>().WithParameter(
new ResolvedParameter(
(pi,ctx) => pi.ParameterType == typeof(IDataProtectionService),(pi,ctx) => ctx.ResolveKeyed<IDataProtectionService>(DeviceState.Db)
)
).As<IMyDbRepo>().SingleInstance();
builder.RegisterType<MyCacheRepo>().WithParameter(
new ResolvedParameter(
(pi,ctx) => ctx.ResolveKeyed<IDataProtectionService>(DeviceState.Cache)
)
).As<IMyCacheRepo>().SingleInstance();
var container = builder.Build();
var cache = container.Resolve<IMyCacheRepo>();
var db = container.Resolve<IMyDbRepo>();
}
}
public enum DeviceState { Cache,Db }
public class DataProtectionServiceModule : Module
{
private readonly string config;
private readonly DeviceState _state;
public DataProtectionServiceModule(string config,DeviceState state)
{
this.config = config;
_state = state;
}
protected override void Load(ContainerBuilder builder)
{
builder.Register<Token>(compContext =>
{ // a complex logic here
}).OnRelease(instance => instance.Dispose());
builder.Register(c =>
{
// a logic to generate an object of IDataProtectionService
// this logic involves the use of config field of this class.
return new DataProtectionService(config);
}).Keyed<IDataProtectionService>(_state);
}
}
public class DataProtectionService : IDataProtectionService
{
public string Config { get; }
public DataProtectionService(string config)
{
Config = config;
}
}
public class MyDbRepo : IMyDbRepo
{
IDataProtectionService dataProtectionService;
public MyDbRepo(IDataProtectionService dataProtectionService)
{
this.dataProtectionService = dataProtectionService;
}
}
public interface IDataProtectionService
{
}
public interface IMyDbRepo
{
}
public class MyCacheRepo : IMyCacheRepo
{
IDataProtectionService dataProtectionService;
public MyCacheRepo(IDataProtectionService dataProtectionService)
{
this.dataProtectionService = dataProtectionService;
}
}
public interface IMyCacheRepo
{
}
或者,您可以使用 Named Services 以及配置名称 dbConfig
和 cacheConfig
。这样您就不需要更改 DataProtectionServiceModule
的构造函数。
builder.RegisterType<MyDbRepo>().WithParameter(
new ResolvedParameter(
(pi,ctx) => ctx.ResolveNamed<IDataProtectionService>("dbConfig")
)
).As<IMyDbRepo>().SingleInstance();
builder.RegisterType<MyCacheRepo>().WithParameter(
new ResolvedParameter(
(pi,ctx) => ctx.ResolveNamed<IDataProtectionService>("cacheConfig")
还有你的模块:
protected override void Load(ContainerBuilder builder)
{
//builder.Register<Token>(compContext =>
//{ // a complex logic here
//}).OnRelease(instance => instance.Dispose());
builder.Register(c =>
{
// a logic to generate an object of IDataProtectionService
// this logic involves the use of config field of this class.
return new DataProtectionService(config);
}).Named<IDataProtectionService>(config);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。