Osadzanie zespołów wewnątrz innego zespołu

Jeśli utworzysz bibliotekę klas, która używa rzeczy z innych zestawów, czy możliwe jest osadzenie tych innych zestawów w bibliotece klas jako pewnego rodzaju zasobu?

Czyli zamiast mieć Mójdll, some Assembly1.dll i SomeAssembly2.dll siedząc w systemie plików, te dwa pozostałe pliki są dołączane do MyAssembly.dll i są użyteczne w jego kodzie.


Jestem też trochę zdezorientowany, dlaczego. NET składy są .pliki dll . Czy ten format nie istniał przed. NET? czy wszystkie biblioteki DLL. NET assemblies, ale nie wszystkie biblioteki DLL są. NET assemblies? Dlaczego używają tego samego formatu pliku i / lub rozszerzenia pliku?

Author: Peter Mortensen, 2008-10-21

8 answers

Spójrz na ILMerge do łączenia zespołów.

Jestem też trochę zdezorientowany, dlaczego. NET assemblies są .pliki dll. Czy ten format nie istniał przed. NET?

Tak.

Są wszystkimi bibliotekami DLL. NET,

Albo DLL lub EXE normalnie - ale może być również netmodule.

Ale nie wszystkie biblioteki DLL są. NET assemblies?

Zgadza się.

Dlaczego używają tego samego formatu pliku i / lub pliku przedłużenie?

Dlaczego miałoby być inaczej - służy temu samemu celowi!

 35
Author: AtliB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-16 15:12:41

ILMerge łączy zespoły, co jest miłe, ale czasami nie do końca to, czego chcesz. Na przykład, jeśli dany zespół jest ściśle nazwany, a nie masz do niego klucza, nie możesz wykonać ILMerge bez złamania tego podpisu. Co oznacza, że musisz wdrożyć wiele zespołów.

Jako alternatywa dla ilmerge, możesz osadzić jeden lub więcej zestawów jako zasoby w exe lub DLL. Następnie, w czasie wykonywania, gdy składy są ładowane, można programowo rozpakuj osadzony zespół, załaduj go i uruchom. To brzmi skomplikowanie, ale jest tylko trochę kodu boilerplate.

Aby to zrobić, osadzić zespół, tak jak osadzić każdy inny zasób (obraz, plik tłumaczenia, dane itp.). Następnie skonfiguruj AssemblyResolver, który zostanie wywołany w czasie wykonywania. Powinien być ustawiony w statycznym konstruktorze klasy startowej. Kod jest bardzo prosty.

    static NameOfStartupClassHere()
    {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(Resolver);
    }

    static System.Reflection.Assembly Resolver(object sender, ResolveEventArgs args)
    {
        Assembly a1 = Assembly.GetExecutingAssembly();
        Stream s = a1.GetManifestResourceStream(args.Name);
        byte[] block = new byte[s.Length];
        s.Read(block, 0, block.Length);
        Assembly a2 = Assembly.Load(block);
        return a2;
    }

Właściwość Name w parametrze ResolveEventArgs jest nazwa zgromadzenia, które ma zostać rozwiązane. Ta nazwa odnosi się do zasobu, a nie do nazwy pliku. Jeśli osadzono plik o nazwie " MyAssembly.dll "i wywołać osadzony zasób "Foo" , a następnie nazwa, którą chcesz tutaj jest "Foo". Ale to byłoby mylące, więc sugeruję użycie nazwy pliku Złożenia dla nazwy zasobu. Jeśli osadzono i nazwałeś swój zespół poprawnie, możesz po prostu wywołać metodę GetManifestResourceStream () z nazwą złożenia i załadować w ten sposób. Bardzo proste.

Działa to z wieloma złożeniami, tak samo dobrze jak z pojedynczym osadzonym złożeniem.

W prawdziwej aplikacji będziesz potrzebował lepszej obsługi błędów w tej rutynie - na przykład co, jeśli nie ma strumienia o danej nazwie? Co się stanie, jeśli odczyt się nie powiedzie? itd. Ale to pozostało do zrobienia.

W pozostałej części kodu aplikacji, types from the assembly są używane normalnie.

Kiedy budujesz aplikację, musisz dodać odniesienie do danego zestawu, ponieważ normalnie. Jeśli używasz narzędzi wiersza poleceń, użyj opcji /r W csc.exe; jeśli używasz Visual Studio, musisz " dodać odniesienie..."w menu podręcznym projektu.

Podczas wykonywania, sprawdzanie i weryfikacja wersji assembly działa jak zwykle.

Jedyna różnica polega na rozkładzie. Gdy wdrażasz lub rozpowszechniasz aplikację, nie musisz rozpowszechniać biblioteki DLL dla osadzonego (i odwoływanego) zestawu. Wystarczy wdrożyć główny zespół; nie ma potrzeby rozprowadzania drugiego złożeń, ponieważ są one osadzone w głównej DLL lub EXE.

 58
Author: Cheeso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-09 13:02:44

Możesz osadzić assembly (lub dowolny plik) jako zasób (a następnie użyć klasy ResourceManager, aby uzyskać do nich dostęp), ale jeśli chcesz po prostu połączyć Assembly, lepiej użyć narzędzia takiego jak ILMerge .

Pliki EXE i DLL są plikami wykonywalnymi Windows portable , które są wystarczająco ogólne, aby pomieścić przyszłe Typy kodu, w tym dowolny kod. NET (mogą również działać w DOS-ie, ale wyświetlają tylko komunikat, że nie powinny działać w DOS-ie). Oni Dołącz instrukcje, aby uruchomić. NET runtime, jeśli jeszcze nie jest uruchomiony. Możliwe jest również, aby pojedynczy zespół obejmował wiele plików, choć rzadko tak się dzieje.
 8
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 17:11:24

Uwaga ILMerge nie działa z wbudowanymi zasobami, takimi jak XAML, więc aplikacje WPF itp. będą musiały użyć metody Cheeso.

 5
Author: Richard Dingwall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-13 22:51:13

Istnieje również narzędzie mkbundle oferowane przez projekt Mono

 4
Author: hova,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-21 17:19:42

Dlaczego używają tego samego formatu pliku i / lub rozszerzenia pliku?

Dlaczego miałoby być inaczej - służy temu samemu celowi!

Moje 2¢ trochę wyjaśnienia tutaj: DLL jest dynamiczna biblioteka Link. Oba w starym stylu .dll (kod C) i styl .NET.dll są z definicji bibliotekami "dynamic link". Więc .dll jest właściwym Opisem dla obu.

 1
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-10 19:53:44

W odniesieniu do odpowiedzi Cheeso na osadzanie złożeń jako zasobów i ładowanie ich dynamicznie przy użyciu przeładowania Load(byte []) przy użyciu obsługi zdarzenia AssemblyResolve, musisz zmodyfikować rozwiązanie, aby sprawdzić AppDomain, czy istniejąca instancja złożeń ładuje się i zwraca istniejącą instancję złożeń, jeśli jest już załadowana.

Assemblies loaded using that overload does not have a context, which can cause the framework to try and reload the assembly multiple razy. Bez zwracania już załadowanej instancji, można skończyć z wieloma instancjami tego samego kodu złożeń i typów, które powinny być równe, ale nie będą, ponieważ framework uważa, że pochodzą z dwóch różnych złożeń.

Co najmniej jednym ze sposobów, w jaki zostanie wykonane wiele zdarzeń AssemblyResolve dla tego samego zestawu załadowanego do kontekstu "No", jest to, że masz odwołania do typów, które wystawia z wielu zestawów załadowanych do Twojej AppDomain, ponieważ kod wykonuje to, czego potrzebujesz te typy rozwiązały się.

Https://msdn.microsoft.com/en-us/library/dd153782%28v=vs.110%29.aspx

Kilka istotnych punktów z linku:

" Inne złożenia nie mogą wiązać się z złożeniami, które są ładowane bez kontekstu, chyba że obsługujesz AppDomain.AssemblyResolve event "

" wczytywanie wielu zestawów o tej samej tożsamości bez kontekstu może powodować problemy z tożsamością typu podobne do tych powodowanych przez wczytywanie zestawów o tej samej tożsamości do wiele kontekstów. Zobacz unikanie ładowania złożenia w wielu kontekstach."

 0
Author: user3447701,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 22:52:21

Proponuję spróbować Costura.Fody . Tylko nie zapomnij zainstalować-pakiet Fody przed Costura.Fody (w celu uzyskania najnowszej Fody!)

 0
Author: Peter Kalef ' DidiSoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-14 09:36:53