Castelul Windsor și auto-înregistrare

voturi
1

Sunt un n00b castel, și sunt, folosind API Fluent în Castelul Windsor la implementările de auto-registru serviciilor bazate pe o convenție de denumire (ISomething este implementat de ceva). Un lucru am vrut să sprijine este pentru auto-înregistrare pentru a ridica dependențe care sunt în DLL-uri separate și auto-înregistrare în cele, de asemenea.

Deci: IFoo este implementat de Foo (atât în ​​Foo.dll) și Foo depinde de Ibar, care este în Bar.dll.

Am următorul cod scrise pentru a efectua de fapt, auto-înregistrare. Se pare să funcționeze, dar mă întreb dacă am făcut prea mult eu la serviciu. Există o modalitate mai simplă de a realiza același lucru?

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);
                   }
               }
            }
        }
    }
Întrebat 12/03/2009 la 14:29
sursa de către utilizator
În alte limbi...                            


2 răspunsuri

voturi
2

Este într - adevăr depinde de modul în care structura și numele componentelor ... dacă vă păstrați niște convenții simple (adică toate serviciile de componente de sub „MyApp.Services“ namespace și implementările lor sub „MyApp.Services.Impl“) ar putea scadea dramatic acest lucru complexitate (vezi de exemplu ayende1 , ayende2 ).

De asemenea, OMI utilitatea acestei este mai degrabă limitată, cu excepția cazurilor cele mai simple ... de exemplu unele servicii doriți să vă înregistrați, fără nici o interfață de serviciu, unele servicii au nevoie de configurare, are prioritate față de serviciu, etc, în cazul în care acest lucru nu va funcționa .

Publicat 12/03/2009 la 18:23
sursa de către utilizator

voturi
0

Nu sunt sigur dacă acest lucru răspunde la întrebarea dvs., dar acest lucru este ceea ce a făcut am să înregistreze automat mele Servicii.

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

Toate serviciile mele moștenesc de la un BaseService (Abstract Class) precum și o interfață - IService. Acest lucru ar lega automat clasa de servicii de beton la interfața sa și să-l disponibile pentru utilizare în container.

Publicat 31/01/2013 la 13:54
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more