2011-01-07 16 views
5

Supponiamo di aver implementato IFoo da Foo e IBar implementati da FirstBar e SecondBar.Castle Windsor: utilizzo della registrazione della convenzione e implementazioni specifiche

Utilizzando questa registrazione convenzione:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 

Avremo tre voci nel contenitore:

IFoo = Foo 
IBar = FirstBar 
IBar = SecondBar 

Ora, come possiamo prelevarlo registrazione per essere in grado di dire il contenitore che per IBar vogliamo solo la registrazione di SecondBar? Ordina:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface() 
     .For<IBar>().Select<SecondBar>()) 

Caso di utilizzo: abbiamo molti servizi nella nostra app tutti registrati per convenzione. Tuttavia, alcune delle interfacce di servizio hanno due o più implementazioni (ad esempio implementazione reale, implementazione falsa e implementazione del test). La registrazione della convenzione li registrerà tutti sotto la stessa interfaccia e mentre risolviamo l'interfaccia otterremo la prima implementazione (in ordine non deterministico). Vogliamo essere in grado di selezionare un'implementazione specifica per tali servizi durante la registrazione. Come possiamo farlo?

risposta

3

Questo è ciò che ha reso il lavoro svolto:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 
     .ConfigureFor<IBar>(c => 
      c.If((k, m) => m.Implementation == typeof(SecondBar))); 

questo modo si registra in modo efficace solo impl SecondBar per il servizio IBar. In questo modo, se ci sono più di una implementazione per un determinato servizio, possiamo dire allo scanner convenzionale quale impl che vogliamo.

Siamo andati avanti e abbiamo creato belle metodi di estensione poco per questo scopo:

public static BasedOnDescriptor Select<TService, TImpl>(this BasedOnDescriptor desc) 
{ 
    return desc.ConfigureFor<TService>(c => c.If((k, m) => m.Implementation == typeof(TImpl))); 
} 

public static BasedOnDescriptor Ignore<TService>(this BasedOnDescriptor desc) 
{ 
    return desc.ConfigureFor<TService>(c => c.If((k, m) => false)); 
} 

ora possiamo usare in questo modo:

container.Register(
    AllTypes.FromThisAssembly().Pick() 
     .WithService.DefaultInterface()) 
     .Select<IBar, SecondBar>() 
     .Ignore<ISomeService>() 

Tutto sommato, questo funziona bene. Credo che quei due metodi potrebbero essere nel castello. Guardiano corretto. @Krzysztof Koźmic: dove posso inviare una patch? :)

+0

Github. Potrebbe essere una buona idea far comparire questo gruppo di utenti del castello su gruppi di google per raccogliere prima il feedback. Cheers –

+0

Sì, Ignore è esattamente ciò di cui ho bisogno – PandaWood

5

Stringa la tua convention. Ovviamente è largo.

container.Register(
    AllTypes.FromThisAssembly() 
     .Where(t => t.Namespace != "Acme.Tests") 
     .WithService.DefaultInterface()) 
Problemi correlati