2010-11-01 15 views
10

Io uso Castle Windsor come il mio IoC container. Ho un'applicazione che ha una struttura simile al seguente:Castle Windsor: tipi di registro automatico da un assembly che implementa interfacce da un altro

  • MyApp.Services.dll
    • IEmployeeService
    • IContractHoursService
    • ...
  • MyApp.ServicesImpl.dll
    • EmployeeService : MyApp.Services.IEmployeeService
    • ContractHoursService : MyApp.Services.IContractHoursService
    • ...

utilizzare la XML configuration in questo momento, e ogni volta che aggiungere una nuova coppia/Servizio IService, devo aggiungere un nuovo componente al XML file di configurazione. Voglio passare tutto questo allo fluent registration API ma non ho ancora risolto esattamente la ricetta giusta per fare quello che voglio ancora.

Qualcuno può aiutare? Gli stili di vita saranno tutti singleton.

Molte grazie in anticipo.

risposta

12

Con AllTypes si può facilmente fare questo:

Da http://stw.castleproject.org/(S(nppam045y0sdncmbazr1ob55))/Windsor.Registering-components-by-conventions.ashx:

componenti Registrazione one-by-one può essere lavoro molto ripetitivo. Inoltre, ricordando di registrare ogni nuovo tipo che si aggiunge può portare rapidamente alla frustrazione. Fortunatamente, non devi farlo, almeno sempre. Utilizzando la classe di voci AllTypes è possibile eseguire la registrazione di gruppo dei tipi in base ad alcune caratteristiche specificate specificate.

penso che la tua registrazione sarà simile:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly) 
    .BasedOn<IEmployeeService>() 
    .LifeStyle.Singleton 

Se si implementa un tipo di base, come IService sulle interfacce, tutti si può registrare in una sola volta con il seguente comando:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly) 
    .BasedOn<IService>() 
    .WithService.FromInterface() 
    .LifeStyle.Singleton 

Per ulteriori esempi, vedere l'articolo. Questo ha una descrizione molto buona su quali sono le possibilità.

+0

Questo non fa al 100% quello che mi serve, però. Ci sono diverse interfacce di servizio nel primo assembly e ho un mapping one-one con un'istanza concreta. Dovrei scrivere il codice sopra più e più volte come faccio per la configurazione xml ora. –

+0

È un'opzione per avere un'interfaccia di base per 'IEmployeeService'? Questo è quello che ho fatto. Puoi dire a Windsor di cercare quell'interfaccia, registrare tutto sotto di esso (quindi, in particolare "IEmployeeService") con le implementazioni dall'assembly. Espansione della risposta con un esempio. –

+0

Vuoi dire avere un semplice 'IService' senza membri che funga da interfaccia marker? Potrebbe funzionare, stavo solo sperando di poterlo evitare. :) –

3

ho preso Pieter's answer in avanti solo un po '(l'essere fondamentale, come ha suggerito, AllTypes) e sono venuti fino a questo:

// Windsor 2.x 
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl") 
    .Where(type => type.IsPublic) 
    .WithService.FirstInterface() 
    ); 

Questo passa attraverso tutte le classi pubbliche nel montaggio MyApp.ServicesImpl.dll e registra ogni nel contenitore usando la prima interfaccia che implementa. Perché voglio tutte le classi nell'assemblaggio dei servizi, non ho bisogno di un'interfaccia marcatore.

Quanto sopra funziona per una vecchia versione di Windsor. La corrente Castle Windsor documentation for registering components per la versione più recente suggerisce quanto segue:

// Windsor latest 
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl") 
    .Where(type => type.IsPublic) // Filtering on public isn't really necessary (see comments) but you could put additional filtering here 
    .WithService.DefaultInterface() 
    ); 
+0

non è necessario' Dove (tipo => tipo .IsPublic) '. In ogni caso, Windsor analizzerà solo i tipi esportati (il che significa pubblico o nidificato). –

+0

L'ho pensato, ma penso che sia necessario 'Where (something)' sebbene il metodo 'WithService' non sia sul valore restituito da' FromAssemblyNamed() '. Oh, a meno che non avessi un errore #intellisense ... controllerò ... –

+0

Ho appena controllato, sicuramente non mi viene compilato. Dato che attualmente mi trovo su una versione precedente di Windsor, presumo che sia finita qui e aggiorno la risposta sopra per quanto riguarda l'ultima di Windsor. Grazie mille per l'input. :) –

Problemi correlati