2011-08-07 10 views
6

mam ten interfejs, który jest używany przez kilka konkretnych typów, takich jak EmailFormatter, TextMessageFormatter itpJak wstrzykiwać właściwą zależność na podstawie konstruktora nazwy parametru

public interface IFormatter<T> 
{ 
    T Format(CompletedItem completedItem); 
} 

Problem mam jest to, że z moim EmailNotificationService jest to, że chcę wstrzyknąć EmailFormatter. Sygnatura konstruktora dla tej usługi to public EmailNotificationService(IFormatter<string> emailFormatter).

Jestem prawie pewien, że widziałem to wcześniej, ale jak mogę zarejestrować to w Windsor, aby wstawić EmailFormatter, jeśli nazwa parametru konstruktora to emailFormatter?

Oto mój kod rejestracyjny Windsor.

container.Register(Component.For<IFormatter<string>>().ImplementedBy<EmailFormatter>()); 

Odpowiedz

6

Kod serwisowy:

public EmailNotificationService(IFormatter<string> emailFormatter){...} 

Zależność kod rejestracyjny:

container.Register(
    Component.For<IFormatter<string>().ImplementedBy<TextMessageFormatter>().Named("TextMessageFormatter"), 
    Component.For<IFormatter<string>().ImplementedBy<EmailFormatter>().Named("EmailFormatter"), 
    Component.For<INotificationService>().ImplementedBy<EmailNotificationService>().ServiceOverrrides(
     ServiceOverride.ForKey("emailFormatter").Eq("EmailFormatter")) 
); 
+0

Dzięki za odpowiedź. Szukałem złych rzeczy. : D – User

+0

Cieszę się, że mogę pomóc. –

9

Nie próbować rozwiązać ten problem w konfiguracji DI. Zamiast tego rozwiąż go w projekcie aplikacji. Wydaje mi się, że zdefiniowałeś kilka różnych rzeczy za pomocą tego samego interfejsu. Twoje wymagania czyni to dość oczywiste, ponieważ mówicie:

chcę wstrzykiwać EmailFormatter

Nie chce wstrzyknąć formatowania; chcesz wstrzyknąć program do formatowania wiadomości e-mail. Innymi słowy, naruszasz kod Liskov Substitution Principle. Napraw ten problem w aplikacji. Zdefiniować interfejs IEmailFormatter i niech EmailNotificationService zależy od tego:

public interface IEmailFormatter 
{ 
    string Format(CompletedItem completedItem); 
} 

public class EmailNotificationService 
{ 
    public EmailNotificationService(IEmailFormatter formatter) 
    { 
    } 
} 

ten ma dwie ważne zalety:

  1. To sprawia, że ​​kod bardziej linkujących, ponieważ teraz jest jasne, jaki rodzaj uzależnienia EmailNotificationService naprawdę ma .
  2. Dzięki temu konfiguracja DI jest łatwiejsza i łatwiejsza w utrzymaniu. Wystarczy spojrzeć na rejestrację zależności Zacha, a zrozumiesz, o czym mówię.
+0

Rozumiem, co masz na myśli, ale czy nie jest to zbyteczne dzięki oddzielnym interfejsom, które wszystkie wykonują jedną rzeczą, formatują treść? – User

+2

@User: posiadanie 'EmailNotificationService' zależy od' IFormatter 'implikuje, że każdy program formatujący string mógłby zrobić dobrze, podczas gdy może on działać poprawnie tylko z formaterem, który może wysyłać wiadomości e-mail. Więc, co dotyczy "EmailNotificationService", to nie to samo. Podczas gdy 'IMailFormatter' i' IFormatter 'mają takie same typy wejścia i wyjścia, kontrakt' IMailFormatter' jest silniejszy, ponieważ wyraźnie mówi, jaki rodzaj ciągu zwraca, podczas gdy 'IFormatter ' może zwrócić wszystko. – Steven