Aquí podría ser tu PUBLICIDAD


Castle Windsor y registro automático

votos
1

Soy Castle n00b y estoy usando la API Fluent en Castle Windsor para registrar automáticamente las implementaciones en servicios basados ​​en una convención de nomenclatura (ISomething es implementado por Something). Una cosa que quería apoyar es que el registro automático recoja las dependencias que están en dlls separadas, y que también las registre automáticamente.

Entonces: IFoo es implementado por Foo (ambos en Foo.dll), y Foo depende de IBar, que está en Bar.dll.

Tengo el siguiente código escrito para realizar el registro automático. Parece que funciona, pero me pregunto si también trabajé demasiado. ¿Hay una manera más simple de lograr lo mismo?

private static void EnsureRegistered(Type t, IWindsorContainer container)
    {
        if (!container.Kernel.HasComponent(t) && (!(t.Assembly.FullName.StartsWith(System) || t.Assembly.FullName.StartsWith(mscorlib))))
        {
            bool registeredAtLeastOneComponent = false;

            container.Register(AllTypes.Pick().
                   FromAssembly(t.Assembly).If(delegate(Type t2)
                       {
                           //auto-registers all types that implement an interface where
                           //the name of the interface is the same as the class, minus the 'I'
                           //ex: EchoService is auto-registered as handler of IEchoService
                           Type[] interfaces = t2.GetInterfaces();
                           bool shouldRegister = false;
                           foreach(Type interfaceType in interfaces)
                           {
                               shouldRegister = t2.Name.Equals(interfaceType.Name.Substring(1))
                                                     && (!container.Kernel.HasComponent(interfaceType));
                               registeredAtLeastOneComponent = registeredAtLeastOneComponent || shouldRegister;
                               if (shouldRegister)
                                   break;
                           }
                           return shouldRegister;

                       }).WithService.Select(delegate(Type type, Type baseType)
                         {
                             Type serviceType = null;
                             Type[] interfaces = type.GetInterfaces();
                             foreach(Type interfaceType in interfaces)
                             {
                                 if (!type.Name.Equals(interfaceType.Name.Substring(1))) continue;
                                 serviceType = interfaceType;
                                 break;
                             }

                             return new Type[] {serviceType};

                         }));

            if (!registeredAtLeastOneComponent)
                return;

            //for each of the items in the graph, if they have see if they have dependencies
            //in other assemblies that aren't registered, register those dependencies as well
            foreach(GraphNode registered in container.Kernel.GraphNodes)
            {
               if (!(registered is Castle.Core.ComponentModel))
                    continue;

               Castle.Core.ComponentModel registeredComponent = registered as Castle.Core.ComponentModel;

               foreach(ConstructorCandidate constructor in registeredComponent.Constructors)
               {
                   foreach(DependencyModel dep in constructor.Dependencies)
                   {
                       EnsureRegistered(dep.TargetType, container);
                   }
               }
            }
        }
    }
Publicado el 12/03/2009 a las 16:29
fuente por usuario Craig Vermeer
En otros idiomas...        العربية       

2 respuestas

votos
2

Realmente depende de cómo estructurar y nombrar sus componentes ... si mantiene algunas convenciones simples (es decir, todos los servicios de componentes en los espacios de nombres "MyApp.Services" y sus implementaciones en "MyApp.Services.Impl"), podría disminuir drásticamente esta complejidad (ver por ejemplo ayende1 , ayende2 ).

Además, IMO la utilidad de esto es bastante limitada, excepto para los casos más simples ... por ejemplo, algunos servicios que desea registrar sin ninguna interfaz de servicio, algunos servicios necesitan configuración, anulaciones de servicio, etc. en cuyo caso esto no funcionará .

Respondida el 12/03/2009 a las 08:23
fuente por usuario Mauricio Scheffer


Aquí podría ser tu PUBLICIDAD


votos
0

No estoy seguro si esto responde a su pregunta, pero esto es lo que hice para auto registrar mis servicios.

        // Auto-Register Services as Singletons
        container.Register(
            AllTypes.FromAssembly(typeof(BaseService).Assembly).Pick()
                    .WithService.DefaultInterfaces()
                    .Configure(s => s.LifestyleSingleton()));

Todos mis servicios heredan de una BaseService (Resumen clase), así como una interfaz - IService. Esto enlazar automáticamente la clase de servicio concreto a su interfaz y que esté disponible para su uso en el contenedor.

Respondida el 31/01/2013 a las 04:54
fuente por usuario Kwex