Scott Scott - 18 days ago 11
C# Question

Register all classes from base on up in Castle Windsor using Fluent interface

I have an abstract base class

Search
. An abstract class
IndexedRepositorySearch
descends from
Search
. An abstract class
FacetSearch
descends from
IndexedRepositorySearch
. Concrete classes
IngredientFacetSearch
and
RecipeFacetSearch
descend from
FacetSearch
.

Currently we're registering everything that descends from
Search
with Castle Windsor as follows:

AllTypes.FromAssembly(assembly)
.BasedOn<Search.Search>()
.WithServiceBase()
.WithServiceSelf()
.LifestyleTransient()
.AllowMultipleMatches()


When we then call

_container.ResolveAll<FacetSearch>(new { searchInput = input, searchResults });


It does not resolve anything from the container. When I put a breakpoint on the container after everything has been registered and check
AllComponents
in the debugger, I see both
IngredientFacetSearch
and
RecipeFacetSearch
, but they each only have two Services associated with them: their self and
Search
, their base. Which you would expect given that they registered with
.WithServiceBase()
and
.WithServiceSelf()
.

So the question is how to get them to resolve by calling
ResolveAll<FacetSearch>()
?

I'm sure it's something simple but I'll be darned if I can find it.

Thanks in advance.

Answer

We had a simliar problem to this, but only needed to register the first base which was abstract. I solved it using WithServiceSelect but wrapped it up into an extension method to be used so:

AllTypes.FromAssembly(assembly)
        .BasedOn<Search.Search>()
        .WithServiceLastAbstractBase(),

The definition of the extension method is:

public static BasedOnDescriptor WithServiceLastAbstractBase(this BasedOnDescriptor basedOn)
{
    return basedOn.WithServiceSelect(selectLastAbstractBase);
}

private static IEnumerable<Type> selectLastAbstractBase(Type type, Type[] basetypes)
{
    var baseType = type;

    do
    {
        baseType = baseType.BaseType;
    } while (baseType != null && !baseType.IsAbstract);

    if (baseType == null)
    {
        throw new ArgumentException("There are no abstract base types for: " + type);
    }

    return new [] { baseType };
}