如何在MVVM Light 的SimpleIoc 中注册一个实现了多个接口的class?

How to register a class that implements multiple interfaces in MVVM Light's SimpleIoc?

假设我有几个接口和一个实现它们的class:

public interface ISomething1 { /* blablabla */ }
public interface ISomething2 { /* blablabla */ }
public class Service : ISomething1, ISomething2 { /* blablabla x 2 */ }

我想用这两个接口在 SimpleIoc 中注册 class:

SimpleIoc.Default.Register<ISomething1, Service >();
SimpleIoc.Default.Register<ISomething2, Service >();

但是这里的第二行抛出 ArgumentException 消息:

An item with the same key has already been added.

我原以为这里的关键是界面本身,但显然并非如此。我的想法是使用显式密钥,但我想通过依赖注入获取实例,其中 IoC 只能与无密钥注册表一起使用。

那么我如何在不更改接口或实现本身的情况下在这里使用 SimpleIoc?

查看此处的源代码 (SimpleIoc.cs on CodePlex) 已经揭示了问题所在。当使用 register 函数的重载时:

public void Register<TInterface, TClass>(bool createInstanceImmediately)

正如预期的那样,它会将 TInterfaceTClass 添加到以接口为键的字典中,但是它还会添加 TClass 及其构造函数到另一个字典,其中 class 是键,无需任何进一步检查。

我怀疑这是一个错误,好像 TClass 是已知的(即添加到此构造函数查找映射中)它可以简单地接受它。


解决方案:

解决方案/变通方法是使用注册工厂类型。这按预期工作:

SimpleIoc.Default.Register<ISomething1>(() => new Service());
SimpleIoc.Default.Register<ISomething2>(() => new Service());

可能这是一个更好的解决方案,因为 Service() 构造函数可以在 ioc 容器中注册依赖项。

SimpleIoc.Default.Register<Service>();
SimpleIoc.Default.Register<ISomething1>(() => SimpleIoc.Default.GetInstance<Service>());
SimpleIoc.Default.Register<ISomething2>(() => SimpleIoc.Default.GetInstance<Service>());