解析 IEnumerable团结一致
Unity 可以自动解析 IEnumerable
吗?
假设我有一个带有此构造函数的类:
public CoalescingParserSelector(IEnumerable<IParserBuilder> parserBuilders)
并且我在容器中配置了单独的 IParserBuilder 实例:
container.RegisterType<IParserSelector, CoalescingParserSelector>();
container.RegisterType<IParserBuilder, HelpParserBuilder>();
container.RegisterType<IParserBuilder, SomeOtherParserBuilder>();
我可以在不必实现 IEnumerable
的自定义实现的情况下完成这项工作吗?
var selector = container.Resolve<IParserSelector>();
到目前为止,我还无法以任何简单的方式表达这一点,但我仍在加强 Unity,所以我可能错过了一些东西。
Can Unity automatically resolve IEnumerable<T>
?
Let's say I have a class with this constructor:
public CoalescingParserSelector(IEnumerable<IParserBuilder> parserBuilders)
and I configure individual IParserBuilder instances in the container:
container.RegisterType<IParserSelector, CoalescingParserSelector>();
container.RegisterType<IParserBuilder, HelpParserBuilder>();
container.RegisterType<IParserBuilder, SomeOtherParserBuilder>();
can I make this work without having to implement a custom implementation of IEnumerable<IParserBuilder>
?
var selector = container.Resolve<IParserSelector>();
So far I haven't been able to express this in any simple way, but I'm still ramping up on Unity so I may have missed something.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
事实证明,这实际上非常简单:
Unity 本身就理解数组,因此我们只需将可枚举映射到相同类型的数组即可。
It turns out that this is actually awfully simple to do:
Unity natively understands arrays, so we just need to map the enumerable to an array of the same type.
@Metro Smurf:你的回答让我走上了正轨:Unity 无法自动解析
IEnumerable
依赖项。我无法编译您的示例,因为
RegisterType
方法不采用InjectionConstructor
实例作为参数。另请注意,仅当您使用不同名称注册了多个类型时,
ResolveAll
方法才有效,并且此方法不会返回默认(未命名)注册的实例。 (顺便说一句,我完全不同意这种行为)。这对我有用:
为了解析单个实例,您还需要添加默认注册,否则对
Resolve()
的调用将失败。此代码使默认注册启用单一分辨率:
@Metro Smurf: your answer got me in the right track: Unity is unable to automatically resolve
IEnumerable<T>
dependencies.I wasn't able to compile your example since the
RegisterType
method doesn't take anInjectionConstructor
instance as parameter.Also note that the
ResolveAll
method will only work if you've registered multiple types with different names and also this method does NOT return an instance for the default (unnamed) registration. (I completely disagree with this behavior btw).This is what worked for me:
In order to resolve a single instance you will need to also add a default registration otherwise the call to
Resolve<T>()
will fail.This code makes the default registration to enable single resolution:
如果你想普遍支持 IEnumerable,那么你可以添加这一行:
This is he generic version of
If you want to generally support IEnumerable, then you can add this line:
This is he generic version of
我相信您需要使用 ResolveAll 方法并使用显式InjectionConstructor 对象,即:
换句话说,我不认为Unity能够自动解析类型的所有实例,并知道在具有 IEnumerable 参数的类上使用构造函数注入,而无需显式声明 InjectionConstructor 对象位于运行时< /a>.
当然,我还在学习 Unity,但这就是我的经验 (YMMV)。
I believe you'll need to use the ResolveAll method and use an explicit InjectionConstructor object, i.e.:
In other words, I don't think Unity is able to automatically resolve all instances of a type and know to use constructor injection on a class with an IEnumerable parameter without an explicitly declaring an InjectionConstructor object at Run Time.
Granted I'm still learning Unity as well, but this has been my experience (YMMV).
对我有用
的只是记住,当您向容器注册 IParserBuilder 类型时,需要唯一的名称,否则它将始终是一个空数组。所以使用
The
Worked for me only keep in mind that when you register IParserBuilder types with your container an unique name is required otherwise it will Always be an empty array. So use
截至 2010 年 5 月,已有对此的原生支持。请查看此处。
As of May 2010, there is the native support for that. Check it out here.
我这样做了
,它注册了实现
IParserBuilder
的所有内容,因此当您添加新的时,无需添加任何其他代码即可使其出现在构建器列表中。I did this like so
Which registers everything that implements
IParserBuilder
, so when you add a new one you don't need to add any other code for it to appear in the list of builders.你可以这样做:
You can do like this: