2011-01-07 13 views
5

Załóżmy, że mamy IFoo wdrożone przez Foo i IBar zaimplementowane przez FirstBar i SecondBar.Castle Windsor: Używanie rejestracji konwencji wraz z konkretnymi implementacjami

Stosując tę ​​rejestrację konwencji:

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

będziemy mieli trzy wpisy w pojemniku:

IFoo = Foo 
IBar = FirstBar 
IBar = SecondBar 

Teraz, w jaki sposób możemy dostosować tej rejestracji, aby móc powiedzieć, że do pojemnika IBar chcemy rejestrować tylko SecondBar? Sortuj według:

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

Przypadek użycia: mamy wiele usług w naszej aplikacji zarejestrowanych przez konwencje. Jednak niektóre interfejsy usług mają dwie lub więcej implementacji (na przykład rzeczywistą implementację, fałszywą implementację i implementację testową). Rejestracja Konwentowa zarejestruje je wszystkie pod tym samym interfejsem i podczas rozwiązywania interfejsu otrzymamy pierwszą implementację (w niedeterministycznej kolejności). Chcemy być w stanie wybrać jedną konkretną implementację dla tych usług podczas rejestracji. Jak możemy to zrobić?

Odpowiedz

3

To właśnie sprawiło, że prace:

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

To skutecznie rejestruje tylko Impl SecondBar serwisu IBAR. W ten sposób, jeśli istnieje więcej niż jedna implementacja dla danej usługi, możemy powiedzieć konwencjonalny skaner, który chcemy impl.

Poszliśmy do przodu i stworzyli ładne małe metody rozszerzenie do tego celu:

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)); 
} 

Możemy teraz używać go tak:

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

W sumie to działa dobrze. Wierzę, że te dwie metody mogą być w Castle.Windsor właściwe. @Krzysztof Koźmic: gdzie mam przesłać łatkę? :)

+0

Github. Dobrym pomysłem może być przeniesienie tego na grupę użytkowników zamków w grupach google, aby najpierw zebrać opinie. Pozdrowienia –

+0

Tak, Ignoruj ​​jest dokładnie tym, czego potrzebuję – PandaWood

5

Dokręcić konwencję. Oczywiście jest szeroki.

container.Register(
    AllTypes.FromThisAssembly() 
     .Where(t => t.Namespace != "Acme.Tests") 
     .WithService.DefaultInterface()) 
Powiązane problemy