我试图设置一个容器来注册一个接受其构造函数为IDictionary<string, IInterface>
的类,所以在我的IoC中我想知道如何获取一个命名实例(如果该功能可用)在SI)。我想要实现的一个例子是:
container.Register<IOtherInterface>(() =>
new OtherInterface(new Dictionary<string, IInterface>
{
{ "a", container.GetInstance<IInterface>("named-a") },
{ "b", container.GetInstance<IInterface>("named-b") },
});
有没有办法配置它?
更新:
界面的实现是具有不同参数的同一个对象,这是我在SI文档https://simpleinjector.readthedocs.io/en/latest/howto.html#resolve-instances-by-key中无法看到的一个例子。我想避免这样一个事实:我必须为字典中的每个值实例化一个新的接口(带有相关参数......),这就是为什么我认为命名注册是可用的在SI。
也许我的方法是错误的,我应该尝试以不同的方式建立依赖关系。
使用示例:
public class OtherInterface : IOtherInterface
{
private readonly IDictionary<string, IInterface> _interfces;
public OtherInterface(IDictionary<string, IInterface> interfaces)
{
_interfaces = interfaces;
}
public void DoSomething(MyRequest request)
{
if(_interfaces.ContainKey(request.SelectMyInterface))
{
_interfaces[request.SelectMyInterface].DoSpecificStuff();
}
}
}
我可以扩展接口IInterface并在这里使用类似Applies(string type)
的方法应用策略模式,但我在过去使用过Ninject的字典方法。
答案 0 :(得分:1)
通过手动创建InstanceProducer
个实例',在Simple Injector中完成键控注册,如下所示:
var a = Lifestyle.Transient.CreateProducer<IInterface, A>(container);
var b = Lifestyle.Transient.CreateProducer<IInterface, B>(container);
使用这些实例生成器,您可以按如下方式进行字典注册:
container.Register<Dictionary<string, IInterface>(() => new Dictionary<string, IInterface>
{
{ "a", a.GetInstance() },
{ "b", b.GetInstance() },
});
您的OtherInterface
看起来像是我的调度员。如果唯一的工作是路由传入的请求,我会说没关系。
但是,我想提出一些不同的设计,而不是注入一个包含已创建实例的完整列表的字典:
public class OtherInterface : IOtherInterface
{
private readonly IDictionary<string, Func<IInterface>> _interfces;
public OtherInterface(IDictionary<string, Func<IInterface>> interfaces) {
_interfaces = interfaces;
}
public void DoSomething(MyRequest request) =>
_interfaces[request.SelectMyInterface].Invoke().DoSpecificStuff();
}
这里的字典包含Func<IInterface>
。这样就可以动态创建实现,而无需在每次调用时创建所有实现。
您可以按如下方式注册:
container.RegisterSingleton<IOtherInterface>(new OtherInterface(
new Dictionary<string, Func<IInterface>>
{
{ "a", CreateProducer<A>() },
{ "b", CreateProducer<B>() },
});
private Func<IInterface> CreateProducer<T>() where T : IInterface =>
Lifestyle.Transient.CreateProducer<IInterface, T>(this.container).GetInstance;
或者,您可能会受益于here所描述的设计(并在here中进行了更详细的解释),尽管您的问题提供的上下文数量有限,但有点难以理解。< / p>