(W związku z tym pytaniem, EF4: dlaczego tworzenie serwera proxy musi być włączone, gdy jest włączone ładowanie z opóźnieniem? ).
Jestem nowy w DI, więc wytrzymaj ze mną. Rozumiem, że kontener jest odpowiedzialny za tworzenie instancji wszystkich moich zarejestrowanych typów, ale w tym celu wymaga odwołania do wszystkich bibliotek DLL w moim rozwiązaniu i ich odwołań.
Gdybym nie używał kontenera DI, nie musiałbym odwoływać się do biblioteki EntityFramework w mojej aplikacji MVC3, tylko do mojej warstwy biznesowej, która odwoływałaby się do mojej warstwy DAL / Repo.
Wiem, że na koniec dnia wszystkie biblioteki DLL znajdują się w folderze bin, ale mój problem polega na tym, że muszę jawnie odwoływać się do niego za pomocą opcji „dodaj odniesienie” w VS, aby móc opublikować WAP ze wszystkimi niezbędnymi plikami.
Odpowiedzi:
Tak, to jest dokładnie sytuacja, której DI tak bardzo stara się uniknąć :)
W przypadku ściśle powiązanego kodu każda biblioteka może mieć tylko kilka odniesień, ale te ponownie mają inne odniesienia, tworząc głęboki wykres zależności, taki jak ten:
Ponieważ wykres zależności głęboko, oznacza to, że większość bibliotek przeciągania wraz z wieloma innymi zależne - na przykład w schemacie biblioteki C wlecze Biblioteka H, E, Library Biblioteka J, M, Library Biblioteka K i biblioteki N . Utrudnia to ponowne użycie każdej biblioteki niezależnie od reszty - na przykład w testach jednostkowych .
Jednak w luźno powiązanej aplikacji, po przeniesieniu wszystkich odwołań do katalogu głównego kompozycji , wykres zależności jest poważnie spłaszczony :
Jak ilustruje zielony kolor, teraz możliwe jest ponowne użycie Biblioteki C bez przeciągania niechcianych zależności.
Jednak wszystko to powiedziawszy, w przypadku wielu kontenerów DI nie trzeba dodawać twardych odwołań do wszystkich wymaganych bibliotek. Zamiast tego można użyć późnego wiązania w postaci skanowania zestawu opartego na konwencji (preferowane) lub konfiguracji XML.
Kiedy to zrobisz, musisz jednak pamiętać o skopiowaniu zestawów do folderu bin aplikacji, ponieważ nie dzieje się to już automatycznie. Osobiście rzadko uważam, że jest to warte dodatkowego wysiłku.
Bardziej rozbudowaną wersję tej odpowiedzi można znaleźć w tym fragmencie mojej książki Dependency Injection, Principles, Practices, Patterns .
źródło
Nawet w przypadku korzystania z kontenera DI nie musisz zezwalać na odwołanie do EF projektu MVC3, ale (niejawnie) decydujesz się to zrobić, implementując element główny kompozycji (ścieżkę startową, w której tworzysz wykresy obiektów) w projekcie MVC3. Jeśli bardzo rygorystycznie podchodzisz do ochrony granic architektonicznych za pomocą zespołów, możesz przenieść logikę prezentacji do innego projektu.
Po przeniesieniu całej logiki związanej z MVC (kontrolery itp.) Z projektu startowego do biblioteki klas, pozwala to zestawowi warstwy prezentacji pozostać odłączonym od reszty aplikacji. Twój projekt aplikacji internetowej sam stanie się bardzo cienką powłoką z wymaganą logiką uruchamiania. Projekt aplikacji internetowej będzie katalogiem głównym kompozycji, który będzie odwoływał się do wszystkich innych zestawów.
Wyodrębnienie logiki prezentacji do biblioteki klas może skomplikować sprawę podczas pracy z MVC. Trudniej będzie wszystko połączyć, ponieważ kontrolerów nie ma w projekcie startowym (podczas gdy widoki, obrazy, pliki css muszą prawdopodobnie pozostać w projekcie startowym). Jest to prawdopodobnie wykonalne, ale konfiguracja zajmie więcej czasu.
Ze względu na wady generalnie radzę po prostu zachować główny katalog kompozycji w projekcie internetowym. Wielu programistów nie chce, aby ich zestaw MVC był zależny od zestawu DAL, ale tak naprawdę nie stanowi to problemu. Nie zapominaj, że zestawy są artefaktem wdrażania ; dzielisz kod na wiele zestawów, aby umożliwić oddzielne wdrażanie kodu. Z drugiej strony warstwa architektoniczna jest logicznym artefaktem. Bardzo możliwe (i powszechne) jest posiadanie wielu warstw w tym samym zespole.
W tym przypadku w końcu będziemy mieć główny element kompozycji (warstwę) i warstwę prezentacji w tym samym projekcie aplikacji internetowej (a więc w tym samym zestawie). Mimo że ten zestaw odwołuje się do zestawu zawierającego DAL, warstwa prezentacji nadal nie odwołuje się do warstwy dostępu do danych . To duże wyróżnienie.
Oczywiście, kiedy to robimy, tracimy zdolność kompilatora do sprawdzenia tej reguły architektonicznej w czasie kompilacji, ale nie powinno to stanowić problemu. Kompilator nie może sprawdzić większości reguł architektonicznych i zawsze istnieje coś takiego jak zdrowy rozsądek. A jeśli w Twoim zespole nie ma zdrowego rozsądku, zawsze możesz skorzystać z przeglądu kodu (który każdy zespół powinien zawsze robić w IMO). Możesz także użyć narzędzia takiego jak NDepend (które jest komercyjne), które pomaga Ci zweryfikować reguły architektoniczne. Integracja NDepend z procesem kompilacji może Cię ostrzec, gdy ktoś włączy kod, który narusza taką zasadę architektoniczną.
Możesz przeczytać bardziej szczegółową dyskusję na temat tego, jak działa Composition Root, w rozdziale 4 mojej książki Dependency Injection, Principles, Practices, Patterns .
źródło
Możesz utworzyć osobny projekt o nazwie „DependencyResolver”. W tym projekcie musisz odwołać się do wszystkich swoich bibliotek.
Teraz warstwa UI nie potrzebuje NHibernate / EF ani żadnej innej biblioteki, która nie dotyczy interfejsu użytkownika, z wyjątkiem Castle Windsor.
Jeśli chcesz ukryć Castle Windsor i DependencyResolver w warstwie UI, możesz napisać HttpModule, który wywołuje rejestr IoC.
Mam tylko przykład dla StructureMap:
DefaultControllerFactory nie używa bezpośrednio kontenera IoC, ale deleguje do metod kontenera IoC.
GetController
Delegat jest w StructureMap rejestru (w Windsor powinno być Installer).źródło
źródło