Castle Windsor CollectionResolver: Why doesn't it work on Resolve calls?
I've added the CollectionResolver
as a sub-resolver of my Windsor kernel, and it will properly inject collections of dependencies on resolved objects. That is, if I have
class X { public X(IComponent[] components) { ... } }
container.Register(/* lots of IComponents */);
container.Register(Component.For<X>());
the components
argument to the constructor is properly constructed when I resolve it
container.Resolve<X>()
but if instead I'd just like to get the list of components themselves,
container.Resolve<IComponent[]>()
I get a ComponentNotFound
exception complaining that I have not registered any components for IComponent[]
. I 开发者_如何学运维find this asymmetry counterintuitive as I'm not sure why the kernel should act differently when it is resolving dependencies it found on constructors/properties as compared to when it is resolving dependencies its user would like it to resolve.
The explicit division for Resolve
/ResolveAll
is due to internal and uninteresting implementation details in the container. The collection resolver is a sub depenendcy resolver and as such it only works for dependencies.
I agree it is not really intuitive. Feel free to log a ticket into Windsor's issue tracker about it.
I guess the reason for this behavior is that in the constructor or property injection Castle uses the collection/array notation as an indicator that all the implementations should be returned in the collection. Otherwise you would need a special interface or an attribute to tell it that. And then you would have to explicitly reference Castle's assemblies everywhere.
When resolving directly from the container, however, you are actually specifying the type that needs to be resolved and you can be a lot more expressive (using the API) and you can call ResolveAll
explicitly. So I guess it was a design compromise - implementing IoC containers isn't that simple because you are often bound by the language's constructs.
精彩评论