2011-07-04 16 views
5

Jestem trochę zmieszany wokół wzoru iniekcji Constructor i reguły Don’t call the container; it’ll call you.Wtryskarka konstruktora - gdzie chcesz zadzwonić?

Czy ktoś może mi wytłumaczyć (a może i ktoś inny), jak prawdziwa aplikacja powinna czerpać wszystkie korzyści z DI za pomocą wtrysku Konstruktora? Daję na to jakiś prosty i myślę, że wspólny przykład:

DomainObject 
RepositoryObject 
DaoObject 

Stosunki jest oczywiste (chyba) - RepositoryObject trzeba DaoObject, DomainObject potrzebują repozytorium.

Korzystanie z wtrysku Konstruktor Zakładam, że mogę (w większości przypadków) zapomnieć o NOWYM słowie kluczowym, ale kiedy, gdzie i jak mam utworzyć nowe obiekty (głównie domena)? Muszę pisać fabryki dla wszystkich klas? Czy powinienem odnieść się do DI Container w tej fabryce?

Najlepiej będzie, gdy ktoś pokaże mi przykład prawdziwej aplikacji (proszę nie Asp.Net MVC :)) lub szkicować jakąś strukturę projektu.

+2

Zobacz tę odpowiedź: http://stackoverflow.com/questions/6277771/what-is-a-composition-root-in-context-of-dependency-injection/6277806#6277806 –

+0

@ Mark - OK, Myślę, że rozumiem, ale mam pewne problemy z tworzeniem obiektu domeny. Załóżmy, że stworzyłem obiekt kontrolny (Global.asax jako root aplikacji) i teraz mam trochę akcji (post), i muszę utworzyć w tym momencie, powiedzmy - nowa książka i książka wymagają pewnej zależności od c (repozytorium lub coś) . Jak utworzyć ten nowy obiekt? Czy ZAWSZE powinienem podawać tę zależność do obiektu kontrolera, chociaż niektóre z nich są używane WYŁĄCZNIE w celu utworzenia obiektu "Book"? Ta sama sytuacja dotyczy Repositorys (niektóre z ich metod tworzą nowe obiekty domenowe). – mgibas

+1

http://stackoverflow.com/questions/4835046/why-not-use-an-container-to-resolve-dependencies-for-business-object/4836790#4836790 –

Odpowiedz

1

nie dostanę swój związek klasy więc o to bardziej oczywiste ;-) Przykład:

class FooService 
{ 
    IFooRepository FooRepository { get; set; } 

    public Service(IFooRepository fooRepository) 
    { 
     this.FooRepository = fooRepository; 
    } 
} 

class Controller 
{ 
    IFooService FooService { get; set; } 
    IBarService BarService { get; set; } 

    public Controller(IFooService fooService, IBarService barService) 
    { 
     this.FooService = fooService; 
     this.BarService = barService; 
    } 
} 

Jak już powiedziałem - nie ma ani new FooRepository()new FooService() kod w dowolnym miejscu.

+0

Musisz użyć pojemnika, który ma integrację MVC, tj. http://code.google.com/p/autofac/wiki/Mvc3Integration –

+0

Thx, ale wiem, jak używać go w MVC do tworzenia kontrolera, ale co z resztą obiektów (głównie domeny)? – mgibas

+0

Obiekt domeny (obiekty zagnieżdżone) zostanie utworzony automatycznie przez kontener DI w zależności od konfiguracji. Musisz skonfigurować swój kontener DI (za pomocą kodu lub niektórych plików konfiguracyjnych), określając, która klasa powinna być instancją dla każdego argumentu konstruktora. W moim przykładzie powiesz kontenerowi DI, aby utworzyć instancję 'FooService' za każdym razem, gdy zobaczy ona argument typu' IFooService', więc kiedy tworzy kontroler, wie, co przekazać jako argument. –

1

Odpowiedzi i link Marka Seemanna są wystarczające, ale chcę coś dodać. Jako początkujący dla DI (którym jestem), to pytanie zawsze mnie budzi: "Ok, nie ma nowych, ale kiedy i jak moje prawdziwe obiekty są wywoływane i wstrzykiwane?". Zajęło mi trochę czasu, aby zrozumieć i zastosować.

Podczas śledzenia odpowiedzi i linków zobaczysz to. Powinieneś zarejestrować swoje interfejsy i klasy w pliku Global.asax aplikacji dla aplikacji internetowej. Na przykład, jeśli używasz programu Ninject, przejdź do programu nuget i pobierz aplikację Ninject.Eeb (w przypadku formularzy internetowych) i zastosuj ją tak, jak w tym przykładzie: http://azolotar.blog.com/2010/06/22/ninject-2-0-in-webforms/

Punkt końcowy w przykładzie.

  • Global.asax jest dziedziczona z NinjectHttpApplication (który jest w Ninject.Web.dll)
  • metoda CreateKernel jest przesłonięta w tym miejscu można stworzyć jądro i powiedzieć dependecy mapę do pojemnika
  • BasePage: to jest dla formularzy internetowych, więc twój interfejs na stronach zostanie rozwiązany, jeśli wszystkie pochodzą od strony podstawowej.

Dodam to, realizacja BasePage jest dość łatwe (tu jest kod na github) prawdopodobnie już mieć basepage więc dodanie tej linii KernelContainer.Inject (this); do OnInit Twojej strony bazowej może rozwiązać problem. Jedną ostatnią resztą, jeśli zamierzasz użyć czegokolwiek w ascx, powinieneś zastąpić OnInit twojego ascsa, aby kontener mógł rozwiązać zależności.

wiem, że nie powiedział MVC lub internetowych:) Ale logika jest taka sama

  • Ustaw mapę depenceny na początku stosowania (Główny do okien)
  • Ponieważ jej nie internecie no no url bezpośrednio nazywając formularze, możesz to nazwać How to use Ninject in a Windows Forms application?, jak w tym przykładzie.Nie wiem, czy używasz niektórych wzorców MVP lub MVVM, ale może to być punkt wyjścia

Cholera, to nie brzmi nie pomocna odpowiedź, ale w każdym razie, mam nadzieję, że to pomaga.

Powiązane problemy