How do I register classes by both interface and na

2019-07-21 16:20发布

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条回答
爷的心禁止访问
2楼-- · 2019-07-21 16:28

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()
    );
查看更多
登录 后发表回答