我使用的是ServiceLocator
我正在与Unity合作
public ServiceLocator(IUserStore userStore, IProdcutsStore productsStore, ...etc) {}
public IUserStore UserStore
{
get { return userStore; }
}
这一切都运行良好,但我想要对存储库进行惰性实例化,因为它们的使用非常少。
所以我的ServiceLocator
现在看起来像
public ServiceLocator(IUnityContainer container) {}
public IUserStore UserStore
{
get { return (IUserStore)container.Resolve(typeof(IUserStore)); }
}
// ...etc
我现在得到一个非常无用的ResolutionFailedException错误
依赖项的解决方案失败, type = “DomainModel.DataServices.Interface.IUserStore” name =“”。异常消息是: 当前构建操作(构建密钥 建立 键[DomainModel.DataServices.Interface.IUserStore, null])失败:当前类型, DomainModel.DataServices.Interface.IUserStore, 是一个接口,不能 建造。你错过了一个类型吗? 映射? (战略类型 BuildPlanStrategy,索引3)
告诉我我的接口类型无法实例化,因为它是一个接口是毫无意义的。我知道这是一个界面,这就是为什么容器应该为我解决它的原因!
无论如何,这里要注意的是我知道配置中的类型映射很好,因为当我直接注入类型接口而不是尝试延迟加载时,它解决了它没有任何问题。
我错过了什么意味着某些地方必须改变才能以这种方式延迟加载?
更新:我猜这里发生了什么,当我将容器DI到ServiceLocator中时,“main”容器每次都实例化一个新容器,然后没有正确配置。我想也许我需要一些方法来指定我将this
作为容器传递,而不是用新的实例化来解析它。
答案 0 :(得分:3)
你的方向有点错误......首先你有一个可测试的类,它在构造函数中声明了它的依赖关系,你把它变成了不可测试的,在容器里面要求“东西” ......没有好=(
您应该为昂贵的对象实现一些工厂接口并在构造函数中需要它,或者(如果可以的话)切换到Unity 2.0并使用Automatic Factories:
public ServiceLocator(Func<IUserStore> userStoreBuilder)
//...
public IUserStore UserStore
{
get { return userStoreBuilder(); }
}
如果您只想创建该对象的实例一次,可以向该属性添加cahcing,或者使用.NET 4.0,您可以尝试asking Lazy in the constructor。
P.S。哦,是的。并回答你的特殊问题=)如果你还想在其他地方注入你的容器实例,你需要先在自己内部注册=)
container.RegisterInstance<IUnityContainer>(container);
修复(参见注释)不要在自身内部注册Unity容器,这将导致container.Dispose()
中的StackOverflowException,正确的实例将作为依赖注入,而无需注册。