有时我一直在寻找正确使用 IoC 容器的好方法,即:
- 严格在组合根处使用容器。
- 不使用通用的 ServiceLocator(或类似的)来避免可测试性问题。
我现在开始一个学习新东西的个人项目,它是一个 WPF (4.5) MVVM 应用程序,它使用 WCF、EntityFramework 以及其他技术、框架、模式和实践,我想尝试不同的方法来充分利用容器,工厂和相关模式。
我想到的一个想法是创建一个可以在组合根目录下设置的通用工厂,而不是传递容器引用。这应该避免可测试性问题。例如,让我们有一个工厂:
class Factory
{
private static Dictionary<Type, Func<object>> Store = new Dictionary<Type,Func<object>>();
public static void Setup<T>(Func<T> Creation)
{
Store.Add(typeof(T), () => Creation());
}
public static T Create<T>()
{
Func<object> func = (from p in Store where p.Key == typeof(T) select p.Value).FirstOrDefault();
if (func != null) return (T)func();
return default(T);
}
}
所以我们在组合根目录配置它,如下所示:
Factory.Setup(() => container.Resolve<ITest>());
Factory.Setup<ISomeWcfService>(() => new SomeWcfService());
最后,创建一个具体类型:
ITest t = Factory.Create<ITest>();
ISomeWcfService client = Factory.Create<ISomeWcfService>();
现在的问题和想法:
我只是重新发明了服务定位器模式吗?
我知道传递容器是一个坏主意,所以这解决了这个问题并且它不依赖于容器,但这看起来不错还是只是一个坏主意?