当配置文件中的映射正确时,Unity容器ResolutionFailedException

发布于 2024-09-19 10:10:31 字数 1257 浏览 6 评论 0原文

我正在使用一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暮凉 2024-09-26 10:10:31

你正走向一个有点错误的方向......首先你有一个可测试的类,它在构造函数中声明了它的依赖项,然后你把它变成了不可测试的,要求容器内的“东西”......不好 =(

您应该为昂贵的对象实现一些工厂接口并在构造函数中需要它,或者(如果可以的话)切换到 Unity 2.0 并使用 自动工厂

public ServiceLocator(Func<IUserStore> userStoreBuilder)

//...

public IUserStore UserStore 
{ 
   get { return userStoreBuilder(); }
}

如果您只想创建该实例对象一次,您可以向该属性添加缓存,或者使用 .NET 4.0,您可以尝试 在构造函数中询问 Lazy

PS 哦,是的。并回答您的具体问题 =) 如果您仍然想在其他地方注入容器的实例,您需要首先在其自身内部注册 =)

container.RegisterInstance<IUnityContainer>(container);

修复(请参阅评论) 不要在其自身内部注册 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:

public ServiceLocator(Func<IUserStore> userStoreBuilder)

//...

public IUserStore UserStore 
{ 
   get { return userStoreBuilder(); }
}

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 =)

container.RegisterInstance<IUnityContainer>(container);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文