2

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?

1
  • I had never noticed this, v. interesting and surprising behavior. I would have thought this construct would internally resolve to a list of filters however it doesn't even look like this is the end result Commented Mar 19, 2015 at 12:14

1 Answer 1

2

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()
    );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.