Question

UPDATED

I have the following classes / interfaces:

public interface IFoo
{
    (...)
}

public interface IFoo<T> : IFoo
{
    (...)
}

public abstract BaseFoo<T> : IFoo<T>
{
    (...)
}

public Bar : BaseFoo<ConcreteType1>
{
    (...)
}

public Baz : BaseFoo<ConcreteType2>
{
    (...)
}

Using Castle Windsor, how can I register the types Bar and Baz as implementing IFoo?

I already tried unsuccessfully something like:

Register(Types.FromAssembly(typeof (IFoo).Assembly)
        .BasedOn<IFoo>()
        .WithService
        .Select(new List<Type> { typeof(IFoo)})
        .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));
Was it helpful?

Solution

EDIT: the exception stated in the comments tells that the abstract class BaseFoo is trying to be resolved. This is because you use Types which selects all components, even abstract classes. A simple way to avoid this is to use Classes which doesn't have this problem. The documentation states:

Should I use Classes or Types?

There are two ways to start registration by convention. One of them is using Classes static class, like in the example above. Second is using Types static class. They both expose exactly the same methods. The difference between them is, that Types will allow you to register all (or to be precise, if you use default settings, all public ) types from given assembly, that is classes, interfaces, structs, delegates, and enums. Classes on the other hand pre-filters the types to only consider non-abstract classes. Most of the time Classes is what you will use, but Types can be very useful in some advanced scenarios, like registration of interface based typed factories.


This code looks correct - in fact I tried it in with three different WithService calls (Base AllInterfaces and Select) and every single one succeeded. I think that it may be the first part of your selection that may not be correct: Types.FromAssembly(typeof (IFoo).Assembly)

I didn't find any way to get a list of what castle considers when it tries to use the fluent registration but you can use Configure to log the names of the considered components:

c.Register(Classes.FromAssemblyInThisApplication()
    .BasedOn<IFoo>()
    .Configure(x => Console.WriteLine(x.Implementation.Name)) // classes names
    .WithService.Select(new Type[] {typeof(IFoo)})
    .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));

So try checking whether you're using the right assembly, or if your classes are visible to the container

EDIT

This code works:

public interface IFoo
{
}
public interface IFoo<T> : IFoo
{
}
public abstract class BaseFoo<T> : IFoo<T>
{
}
public class Bar : BaseFoo<Bar>
{
}
public class Baz : BaseFoo<Baz>
{
}
// main
var c = new Castle.Windsor.WindsorContainer();
c.Register(Classes.FromAssemblyInThisApplication()
            .BasedOn<IFoo>()
            .Configure(x => Console.WriteLine(x.Implementation.Name))
            .WithService.Select(new Type[] {typeof(IFoo)})
            .Configure(x => x.LifeStyle.Is(LifestyleType.Singleton)));
var all = c.ResolveAll<IFoo>(); // 2 components found
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top