Reputation: 91
(Slightly simplified scenario to highlight the specific issue).
I'm trying to use Castle Windsor to resolve a component, which has a constructor with a single parameter which is an array of a service interface:
public class TestClass<T>
{
public TestClass(IService<T>[] services)
{
...
}
}
The Windsor container is configured to use the ArrayResolver:
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));
This all works fine, and one or more services are injected for various instances of T.
However, for some T, there are no implementations of IService<T>
. The goal would be for the constructor to be called with a zero-length array.
The issue is, if there are no concrete implementations of IService for a given T, how do I register the definition of IService with no implementation, so the container is aware of the type?
I'm current using:
container.Register(
Classes.FromAssembly(Assembly.GetExecutingAssembly())
.BasedOn<IService<>>()
.WithService.FirstInterface());
but since this is driven from the concrete classes, it's obviously not registering any 'unused' IService.
Fallback is to provide a stub implementation of IService for any T which doesn't have a 'real' implementation, but I'd prefer not to pollute the code with many such stubs. (Could also provide through an open generic with some reflection...).
Upvotes: 5
Views: 522
Reputation: 91
Answering my own question, having been directed to it by a colleague...
Registering the ArrayResolver with a second parameter specifies allowing empty arrays - which is the case if the component in question is not registered:
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
so the behaviour is exactly as desired.
Upvotes: 4