I'm trying to use Castle.Windsor (3.2.0.0) convention based registration, but can't seem to figure out how to register classes implementing a particular interface only in a particular namespace.
e.g. what I really want to be able to write is something like this :
container.Register(Classes.FromThisAssembly()
.InNamespace("MyApp.EventHandlers")
.BasedOn(typeof(IHandlesEvent<>))
.WithServiceAllInterfaces()
But I get a warning that seems to imply what this will really do is register everything in the EventHandlers
namespace and then everything in the current assembly that implements IHandlesEvent<>
.
If I run the application this does indeed seem to be what happens. I don't want everything that implements that interface to be registered (for example, some of the implementing classes are Sagas, which need to be manually tracked) and I don't really want everything in that namespace registered.
I really don't want to register the event handlers individually, but I can't see from the Windsor documentation how to do what I need by convention. Is it possible?
I'm surprised too, but I could observe the behavior on Castle 3.2. BasedOn
pushed a warning saying that it would reinitialize the registration: here is my sample code:
namespace WindsorTest
{
public interface IHandlesEvent {}
public interface IDontWantToBeRegistered {}
namespace Select
{
public class SelectClass : IHandlesEvent { }
public class DontRegisterMe : IDontWantToBeRegistered { }
}
namespace DontSelect
{
public class DontSelectClass: IHandlesEvent {}
}
internal class Program
{
private static void Main(string[] args)
{
var container = new WindsorContainer();
container.Register(Classes.FromThisAssembly()
.InNamespace("WindsorTest.Select")
.BasedOn<IHandlesEvent>()
.WithServiceAllInterfaces()
);
foreach (var handler in container.ResolveAll<IHandlesEvent>())
{
Console.WriteLine(handler.GetType().Name);
}
foreach (var handler in container.ResolveAll<IDontWantToBeRegistered>())
{
Console.WriteLine(handler.GetType().Name);
}
Console.ReadLine();
}
}
}
It outputs DontSelectClass
when ran.
However I found a way to start with the base class for your registration and refine it with the namespace afterwards. Just use:
container.Register(Classes.FromThisAssembly()
.BasedOn<IHandlesEvent>()
.If(t => t.Namespace == "WindsorTest.Select")
.WithServiceAllInterfaces()
);