当配置文件中的映射正确时,Unity容器ResolutionFailedException
我正在使用一个 ServiceLocator
,我正在使用 Unity DIing
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 错误
依赖关系解析失败, 类型= “DomainModel.DataServices.Interface.IUserStore”, 名称=“”。异常消息是: 当前构建操作(构建密钥 建造 键[DomainModel.DataServices.Interface.IUserStore, null])失败:当前类型, DomainModel.DataServices.Interface.IUserStore, 是一个接口,不能是 建造的。您是否缺少类型 映射? (策略类型 BuildPlanStrategy,索引 3)
告诉我我的接口类型无法实例化,因为它是一个接口,这是毫无意义的。我知道它是一个接口,这就是容器应该为我解决它的原因!
无论如何,这里要注意的一点是,我知道配置中的类型映射很好,因为当我直接注入类型接口而不是尝试延迟加载时,它毫无问题地解决了它。
我错过了什么,这意味着某些地方必须改变才能以这种方式延迟加载?
更新:我猜测这里发生的情况是,当我将容器注入 ServiceLocator 时,“主”容器每次都会实例化一个新容器,然后该容器配置不正确。我想也许我需要某种方法来指定将 this
作为容器传递,而不是使用新的实例化来解析它。
I was using a ServiceLocator
which i was DIing with Unity
public ServiceLocator(IUserStore userStore, IProdcutsStore productsStore, ...etc) {}
public IUserStore UserStore
{
get { return userStore; }
}
This all worked fine, but I wanted lazy instantiation of the repositories as they have quite sparse use.
So my ServiceLocator
now looks like
public ServiceLocator(IUnityContainer container) {}
public IUserStore UserStore
{
get { return (IUserStore)container.Resolve(typeof(IUserStore)); }
}
// ...etc
I'm now getting a really unhelpful ResolutionFailedException error
Resolution of the dependency failed,
type =
"DomainModel.DataServices.Interface.IUserStore",
name = "". Exception message is: The
current build operation (build key
Build
Key[DomainModel.DataServices.Interface.IUserStore,
null]) failed: The current type,
DomainModel.DataServices.Interface.IUserStore,
is an interface and cannot be
constructed. Are you missing a type
mapping? (Strategy type
BuildPlanStrategy, index 3)
Telling me my interface type cannot be instantiated because it is an interface is pretty pointless. I know it's an interface, that's why the container is supposed to be resolving it for me!
Anyway, the point to note here is that I know the type mapping in the config is fine, as when I was injecting the type interface directly instead of trying to lazy load, it resolved it with no problems.
What am I missing that means something somewhere has to change in order to lazy load this way?
Update: I am guessing what's happening here, is that when I DI the container into the ServiceLocator, the "main" container is instantiating a new container each time which is then not configured properly. I think maybe I need some way to specify that I was to pass this
in as the container, rather than resolve it with a new instantiation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你正走向一个有点错误的方向......首先你有一个可测试的类,它在构造函数中声明了它的依赖项,然后你把它变成了不可测试的,要求容器内的“东西”......不好 =(
您应该为昂贵的对象实现一些工厂接口并在构造函数中需要它,或者(如果可以的话)切换到 Unity 2.0 并使用 自动工厂:
如果您只想创建该实例对象一次,您可以向该属性添加缓存,或者使用 .NET 4.0,您可以尝试 在构造函数中询问 Lazy。
PS 哦,是的。并回答您的具体问题 =) 如果您仍然想在其他地方注入容器的实例,您需要首先在其自身内部注册 =)修复(请参阅评论) 不要在其自身内部注册 Unity 容器,这将导致
container 中出现 StackOverflowException。 Dispose()
,正确的实例将作为依赖项注入,而无需注册。You're going in a somewhat wrong direction... At first you've had a testable class that declared its dependencies in the constructor and you turned it into non-so-testable, asking for "something" inside a container... No good =(
You should either implement some factory interface for your expensive object and require it in the constructor, or (if you can) switch to Unity 2.0 and use the Automatic Factories:
If you want to only create the instance of that object once, you can add cahcing to that property, or with .NET 4.0 you can try asking Lazy in the constructor.
P.S. Oh, yes. And answering your particualr question =) If you still want to inject an instance of your container somewhere else, you need to first register it inside itself =)Fix (see comments) DO NOT register a Unity container inside itself, this will cause StackOverflowException in
container.Dispose()
, the correct instance will be injected as a dependency without the registration.