41 votes

Intégration d'ensembles dans un autre ensemble

Si vous créez une bibliothèque de classe qui utilise des choses à partir d'autres assemblées, est-il possible d'incorporer ces autres assemblées à l'intérieur de la bibliothèque de classe, comme une sorte de ressource?

I. e. au lieu d'avoir MyAssembly.dll, SomeAssembly1.dll et SomeAssembly2.dll assis sur le système de fichiers, ces deux fichiers sont regroupés dans à MyAssembly.dll et sont utilisables dans le code.


Je suis aussi un peu confus au sujet de pourquoi .NET assemblées sont .dll fichiers. N'ai pas ce format existe pas avant .NET? Sont tous .NET assemblées Dll, mais pas toutes les Dll sont .NET assemblées? Pourquoi ont-ils utiliser le même format de fichier et/ou l'extension de fichier?

59voto

Cheeso Points 87022

ILMerge ne fusionner les assemblées, ce qui est agréable, mais parfois, pas tout à fait ce que vous voulez. Par exemple, lors de l'assemblée en question est fortement nommées par l'assemblée, et vous n'avez pas de clé pour cela, alors vous ne pouvez pas faire ILMerge sans rupture de cette signature. Ce qui signifie que vous devez déployer plusieurs assemblées.

Comme une alternative à ilmerge, vous pouvez incorporer une ou plusieurs assemblées des ressources dans votre exe ou DLL. Puis, au moment de l'exécution, lorsque les assemblages sont en cours de chargement, vous pouvez extraire intégré à l'assemblée de la programmation, et de la charge et de l'exécuter. Il semble difficile, mais il ya juste un peu de code réutilisable.

Pour le faire, de l'incorporation d'une assemblée, comme vous le feriez d'intégrer d'autres ressources (image, fichier de traduction, de données, etc). Ensuite, mettre en place un AssemblyResolver qui est appelée lors de l'exécution. Il devrait être créé dans le constructeur statique de démarrage de la classe. 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;
    }

Le Nom de la propriété sur la ResolveEventArgs paramètre est le nom de l'assemblée pour être résolu. Ce nom fait référence à la ressource, et non pour le nom de fichier. Si vous incorporez le fichier nommé "MyAssembly.dll" et d'appeler la ressource incorporée "Foo", puis le nom que vous voulez ici est "Foo". Mais que serait source de confusion, donc je suggère d'utiliser le nom de fichier de l'assemblée pour le nom de la ressource. Si vous avez intégré et un nom à votre assemblée correctement, vous pouvez simplement appeler GetManifestResourceStream() avec le nom de l'assemblage et de la charge de l'assemblage de cette façon. Très simple.

Cela fonctionne avec plusieurs assemblages, tout aussi bien qu'avec un unique intégré de l'assemblée.

Dans une application réelle, vous allez vouloir une meilleure gestion des erreurs dans cette routine, comme si il n'y a aucun cours d'eau par le nom donné? Qu'advient-il si la Lecture échoue? etc. Mais ce qui reste à faire pour vous.

Dans le reste du code de l'application, vous utilisez les types de l'assemblée que la normale.

Lorsque vous générez l'application, vous devez ajouter une référence à l'assemblée en question, comme vous le feriez normalement. Si vous utilisez les outils en ligne de commande, utilisez l'option /r dans csc.exe; si vous utilisez Visual Studio, vous aurez besoin de "Ajouter une Référence..." dans le menu déroulant sur le projet.

Au moment de l'exécution, de l'assemblée de vérification de version et de vérification fonctionne comme d'habitude.

La seule différence est que dans la distribution. Lorsque vous déployez ou distribuer votre application, vous ne devez pas distribuer le fichier DLL pour l'embarqué (et de référence) de l'assemblée. Il vous suffit de déployer l'assemblage principal; il n'y a pas besoin de distribuer les autres assemblées, parce qu'ils sont incorporés dans l'EXE ou DLL.

35voto

AtliB Points 776

Jetez un oeil à ILMerge pour la fusion des assemblées: http://www.microsoft.com/downloads/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&displaylang=en

Je suis aussi un peu confus au sujet de pourquoi .NET assemblées sont .les fichiers dll. N'ai pas ce format existe pas avant .NET?

Oui.

Sont tous .NET assemblées Dll,

Soit les Dll ou EXE normalement, mais peut aussi être netmodule.

mais pas toutes les Dll sont .NET assemblées?

Correct.

Pourquoi ont-ils utiliser le même format de fichier et/ou l'extension de fichier?

Pourquoi devrait-il en être autrement -, il sert le même but!

8voto

Mark Cidade Points 53945

Vous pouvez incorporer une assemblée (ou de n'importe quel fichier, en fait) comme une ressource (et ensuite utiliser l' ResourceManager de la classe pour y accéder), mais si vous voulez juste de combiner des assemblées, il est préférable d'utiliser un outil comme ILMerge.

EXE et DLL fichiers exécutables Windows portable, qui sont suffisamment génériques pour accueillir les futurs types de codes, y compris toute .NET code (ils peuvent également exécuter dans le DOS, mais seulement l'affichage d'un message en disant qu'ils ne sont pas censé fonctionner sous DOS). Elles comprennent des instructions pour lancer le .NET de l'exécution si elle n'est pas déjà en cours d'exécution. Il est également possible pour une seule assemblée à s'étendre sur plusieurs fichiers, mais ce n'est presque jamais le cas.

5voto

Richard Dingwall Points 1092

Remarque ILMerge ne fonctionne pas avec des ressources intégrées telles que XAML. Par conséquent, les applications WPF, etc., devront utiliser la méthode de Cheeso.

4voto

hova Points 2222

Il y a aussi l'utilitaire mkbundle offert par le projet Mono

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X