Incorporation d’assemblages dans un autre assemblage

Si vous créez une bibliothèque de classes qui utilise des éléments d’autres assemblys, est-il possible d’incorporer ces autres assemblys dans la bibliothèque de classes en tant que type de ressource?

Par exemple, au lieu d’avoir MyAssembly.dll , SomeAssembly1.dll et SomeAssembly2.dll assis sur le système de fichiers, ces deux autres fichiers sont intégrés à MyAssembly.dll et sont utilisables dans son code.


Je suis également un peu confus quant à la raison pour laquelle les assemblys .NET sont des fichiers .dll . Ce format n’existait-il pas avant .NET? Toutes les DLL d’assemblys .NET sont-elles, mais toutes les DLL ne sont pas des assemblys .NET? Pourquoi utilisent-ils le même format de fichier et / ou extension de fichier?

Jetez un oeil à ILMerge pour la fusion des assemblages.

Je suis également un peu confus quant à la raison pour laquelle les assemblys .NET sont des fichiers .dll. Ce format n’existait-il pas avant .NET?

Oui.

Toutes les DLL d’assemblys .NET,

DLL ou EXE normalement – mais peut également être netmodule.

mais toutes les DLL ne sont pas des assemblys .NET?

Correct.

Pourquoi utilisent-ils le même format de fichier et / ou extension de fichier?

Pourquoi cela devrait-il être différent – cela sert le même but!

ILMerge fusionne des assemblys, ce qui est bien, mais parfois pas tout à fait ce que vous voulez. Par exemple, lorsque l’assembly en question est un assembly fortement nommé et que vous ne disposez pas de la clé, vous ne pouvez pas faire ILMerge sans casser cette signature. Ce qui signifie que vous devez déployer plusieurs assemblages.

Au lieu de ilmerge, vous pouvez intégrer un ou plusieurs assemblys en tant que ressources dans votre exe ou votre DLL. Ensuite, au moment de l’exécution, lorsque les assemblys sont en cours de chargement, vous pouvez extraire l’assembly incorporé par programme, le charger et l’exécuter. Cela semble compliqué, mais il y a juste un petit peu de code standard.

Pour ce faire, incorporez un assemblage comme vous incorporeriez toute autre ressource (image, fichier de traduction, données, etc.). Ensuite, configurez un AssemblyResolver appelé à l’exécution. Il doit être configuré dans le constructeur statique de la classe de démarrage. Le code est très simple.

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; } 

La propriété Name du paramètre ResolveEventArgs est le nom de l’assembly à résoudre. Ce nom fait référence à la ressource, pas au nom du fichier. Si vous incorporez le fichier nommé “MyAssembly.dll” et appelez la ressource incorporée “Foo”, le nom que vous souhaitez utiliser est “Foo”. Mais ce serait déroutant, alors je suggère d’utiliser le nom de fichier de l’assembly pour le nom de la ressource. Si vous avez incorporé et nommé votre assembly correctement, vous pouvez simplement appeler GetManifestResourceStream () avec le nom de l’assembly et charger l’assembly de cette façon. Très simple.

Cela fonctionne avec plusieurs assemblages, aussi bien qu’avec un seul assemblage intégré.

Dans une vraie application, vous voudrez une meilleure gestion des erreurs dans cette routine – comme s’il n’y avait pas de stream par le nom donné? Que se passe-t-il si la lecture échoue? etc. Mais c’est à vous de faire.

Dans le rest du code de l’application, vous utilisez normalement les types de l’assembly.

Lorsque vous créez l’application, vous devez append une référence à l’assembly en question, comme vous le feriez normalement. Si vous utilisez les outils de ligne de commande, utilisez l’option / r dans csc.exe; Si vous utilisez Visual Studio, vous devrez “Ajouter une référence …” dans le menu contextuel du projet.

Lors de l’exécution, la vérification et la vérification de la version de l’assemblage fonctionnent normalement.

La seule différence réside dans la dissortingbution. Lorsque vous déployez ou dissortingbuez votre application, vous n’avez pas besoin de dissortingbuer la DLL pour l’assembly incorporé (et référencé). Il suffit de déployer l’assemblage principal; il n’est pas nécessaire de dissortingbuer les autres assemblys car ils sont intégrés dans la DLL principale ou EXE.