Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Castle Windsor resolve zero or more implementations

Tags:

(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...).

like image 814
Neil Menzies Avatar asked Jan 03 '17 15:01

Neil Menzies


1 Answers

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.

like image 101
Neil Menzies Avatar answered Sep 24 '22 11:09

Neil Menzies