How do I register classes by both interface and namespace with Windsor?

可紊 提交于 2019-12-11 02:48:56

问题


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'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()
    );


来源:https://stackoverflow.com/questions/29142291/how-do-i-register-classes-by-both-interface-and-namespace-with-windsor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!