2013-02-05 13 views
9

Było wiele postów na ten temat, ale jeszcze nie znalazłem "prawdziwego" rozwiązania.Jak zarządzać zależnościami w Visual Studio/MSBuild

W jaki sposób zarządzać drzewem zależności (zarówno w czasie kompilacji, jak i w czasie wykonywania) przy użyciu plików projektu MSBuild (np. Plików projektu Visual Studio za pośrednictwem odniesień do projektu i pliku)?

Powszechnie wiadomo, że odniesienia projektu z projektów podrzędnych nie zostaną skopiowane do katalogu bin aplikacji, jeśli nie istnieje odniesienie do czasu kompilacji, nawet jeśli istnieje zależność czasu wykonywania, a nawet jeśli właściwość copy-local = true. Dlatego każdy luźno powiązany komponent nie będzie kopiowany.

Hack do rozwiązania tego problemu jest uwzględnienie zależności w projekcie nadrzędnego z copy-local = true. Jednak w zasadzie niszczy to twoje drzewo zależności, ponieważ nie wiesz już, gdzie jest zależność, a ostatecznie, gdy twoja aplikacja rośnie i zmienia się, kończysz wersją piekła DLL. Twój projekt nadrzędny kończy się od 10 s do 100 s bibliotek dll, z których większość to zależności środowiska wykonawczego bibliotek dll w projektach potomnych.

Innym hackerem jest napisanie niestandardowego pliku celów i wywołanie go z każdego pliku projektu: http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html. Ale na pewno jest lepsza opcja. To jest taka rzecz z chleba i masła. Programiści Java nigdy nie muszą zajmować się tak banalnymi problemami.

Z tego, co mogę zebrać, sposobem Microsoftu rozwiązania tego problemu jest zarejestrowanie każdej zależności w GAC dla każdej maszyny deweloperskiej, testowej i produkcyjnej. Ale to jest głupie i denerwujące. Nie będę zawracać sobie głowy tą opcją i wykształcić obalenie.

Unikając opcji GAC, w jaki sposób można użyć MSBuild do zarządzania drzewem zależności, które obejmuje zależności zależne od środowiska wykonawczego? Jak Microsoft to robi? Z pewnością nie uruchamiają plików niestandardowych celów, takich jak ten w powyższym linku.

Mam nadzieję, że ktoś z firmy .NET w tle może zwiększyć i zaoferować kilka prawdziwych porad na ten temat. W przeciwnym razie po prostu będę musiał przepisać wszystkie moje skrypty budujące w NAnt (shudder).

Dzięki wszystko.

UPDATE

W odpowiedzi na niektóre komentarze, po to praktyczny przykład sprawę z mojego obecnego projektu.

Aplikacja jest projektem aplikacji sieci Web, który udostępnia zestaw usług WCF. Ma zewnętrzną domenę DLL zawierającą zewnętrzne klasy usług i wewnętrzną bibliotekę DLL zawierającą wewnętrzne usługi POCO, obiekty domeny i DAO. Istnieje osobna biblioteka DLL integracji zawierająca interfejsy (DTO) dla wszystkich klas domen wewnętrznych, która pozwala nam całkowicie rozdzielić zewnętrzne i wewnętrzne domeny. Całość jest połączona z Spring.net. Mam nadzieję, że jest to jasne, daj mi znać, jeśli potrzebujesz więcej wyjaśnień.

Mój obecny proces kompilacji polega na użyciu MSBuild do wygenerowania pakietu wdrożeniowego dla aplikacji WWW (w TFS Build). Tak więc, podczas gdy całe rozwiązanie jest budowane na początku, tylko dane wyjściowe z aplikacji sieciowej są pakowane. Dlatego też aplikacja internetowa jest traktowana jako root zależności i oczekuję, że wszelkie luźno powiązane referencje potomne powinny zostać skopiowane na kompilację, jeśli są ustawione na "copy-always = true".

Aplikacja internetowa zawiera więc odniesienie do biblioteki DLL domeny zewnętrznej, która zawiera odniesienie do biblioteki DLL domeny wewnętrznej, która zawiera wiele odniesień do bibliotek stron trzecich oraz różne pośrednie i luźno powiązane zależności wymagane przez biblioteki innych firm.

Problem występuje, gdy w domenie wewnętrznej domeny istnieje zależność od innej firmy, np. oracle.dataaccess, który jest wymagany przez NHibernate w czasie wykonywania. Nawet jeśli ustawię "copy-always = true" na tych bibliotekach DLL, nie zostaną one skopiowane do pakietu aplikacji sieci Web. Jedynym sposobem na uwzględnienie ich w pakiecie jest dodanie tych bibliotek DLL do referencji aplikacji sieci Web. Nie chcę tego robić, ponieważ nie mam już znaczącego drzewa zależności.

Mam nadzieję, że to sprawi, że kwestia będzie bardziej przejrzysta. Daj mi znać, jeśli coś jest niejasne. Trudno opisać takie rzeczy.

Jeśli ktoś ma również podobny problem, proszę porozmawiaj i podziel się swoim doświadczeniem.

+0

Tak, zgadzam się z tobą, że dodanie ich do GAC będzie nieskuteczne, ale byłem ciekawy, jak NAnt pomoże ci bardziej w tym przypadku? Również w jaki sposób w Javie takie sytuacje będą obsługiwane? Próbuję uzyskać więcej wskazówek, dzięki czemu mogę dać ci lepszą odpowiedź ... Dziękuję –

+0

Myślę, że chce coś takiego jak maven w Javie. Tak naprawdę szukam czegoś podobnego. http://maven.apache.org/ –

+0

W odbiciu, myślę, że NAnt spowodowałoby więcej problemów. Zaktualizuję oryginalny wpis, podając konkretny przykład problemu. –

Odpowiedz

3

Naprawdę chcę dać ci lepszą odpowiedź, ale niestety nie podałeś wystarczająco dużo informacji o twoim rozwiązaniu/projektach i twoich zależnościach, więc postaram się dać ci kilka pomysłów i mam nadzieję, że jeden z nich zadziała.

  1. Najłatwiej to zrobić, jak pan powiedział jest utworzenie osobnego folderu z wszystkich zależności i utworzyć plik docelowy, który będzie skopiować je do folderu bin. Jeśli masz zależności, które nie zmieniają się często, to może działać. Jeśli inny zespół z Twojej firmy je buduje i często się zmieniają, takie podejście nie jest dobre.

  2. Kolejne proste podejście - jeśli odwołujesz się do swoich zależności od rozwiązania, możesz zmienić ścieżkę kompilacji, tak aby były budowane bezpośrednio w folderze bin głównego projektu. W ten sposób nie musisz się bezpośrednio do nich odwoływać.

  3. Użyj NuGet. Masz oddzielny zespół wytwarzający luźno połączonych zależnościami może dokonać sens utworzenia lokalnego repozytorium Nuget i użyć go do tego http://juristr.com/blog/2012/04/using-nuget-to-distribute-our-company/

Mam nadzieję, że pomaga.

Powiązane problemy