2009-10-20 6 views
14

Disons que nous avons une application composée d'un exécutable et de 5 bibliothèques. Régulièrement, tous ces éléments seront contenus dans un répertoire et les bibliothèques seront chargées à partir de là.C#: répertoire d'assemblage personnalisé

Est-il possible de faire en sorte que je puisse avoir par exemple certaines bibliothèques dans un répertoire appelé Lib, et le reste dans un répertoire appelé Lib2? Pour que le répertoire de l'application ne contienne que l'exécutable lui-même et que les autres assemblys soient contenus dans divers répertoires logiques.

Comment est-ce que je peux faire ceci? Et j'aimerais savoir comment faire le chargement des assemblages, mais aussi comment faire en sorte que la construction de l'application mette les assemblages dans le bon répertoire.

+0

Oui, vous pouvez, par la réponse de DotNetWill. Mais il y a peu à gagner et vous pouvez rencontrer beaucoup de problèmes de maintenance. –

Répondre

30

Vous pouvez ajouter des chemins de recherche supplémentaires à votre app.config afin de charger les assemblages. Par exemple

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <probing privatePath="lib;thirdParty" /> 
    </assemblyBinding> 
</runtime> 

Vous pouvez voir plus de détails here.

+0

Fantastique. Si vous vouliez plus de chemins, ajouteriez-vous une autre balise '', ou ajouteriez-vous un autre '' avec un autre '' tag? – Svish

+0

De même, existe-t-il un moyen d'ajouter ce chemin lors de l'exécution? Par exemple, s'il a été construit en utilisant une sorte de variables d'environnement ou d'autres choses. – Svish

+0

@ Svish # 2: Voir ma réponse. – SLaks

2

Pour copier automatiquement les assemblys dans le dossier dans lequel vous souhaitez qu'ils soient, vous pouvez définir Copy Local sur true pour toutes les références et effectuer une étape de post-construction pour les déplacer dans des sous-répertoires.

Alternativement, vous pouvez définir Copy Local false, et ajoutez les fichiers DLL référencés fichiers du projet dans les sous-répertoires appropriés et mis Build Action à copier dans le répertoire de sortie (Cela permettra de préserver les sous-répertoires)

Le plus flexible Pour que le runtime les trouve, il doit gérer l'événement AppDomain.AssemblyResolve et charger manuellement l'assembly à l'aide de Assembly.LoadFile. Vous auriez besoin d'un moyen pour que votre code sache quels assemblages sont dans quels répertoires.

+0

Cette chose AssemblyResolve pourrait probablement être très utile en effet. Je ne savais pas vraiment à propos de celui-là. Pour ce qui est de la construction, que diriez-vous comme la solution la plus propre? Je pense que les deux semblent un peu désordonnés, mais je n'ai pas vraiment essayé l'un d'entre eux, donc je n'en ai pas vraiment la moindre idée: p – Svish

+0

Si vous utilisez des références d'exécution, alors copiez vers local ne vous aidera pas. c'est-à-dire si vous utilisez des développements d'interface, les modules de plugins ne sont disponibles qu'à l'exécution et les références de temps de conception ne fonctionneront pas dans ce contexte – Krishna

0

Dans votre commentaire, vous mentionnez l'ajout de chemins et d'emplacements lors de l'exécution. Oui vous pouvez, mais vous devez utiliser Assembly.Load(), et éventuellement la réflexion.

11

Si vous voulez gérer manuellement où se assemble à partir, vous avez deux possibilités:

  1. gérer l'événement AppDomain.AssemblyResolve (comme il est décrit par SLaks). Voici l'extrait de code:

    static void Main(string[] args) 
    { 
        ... 
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
        ... 
    } 
    
    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
        string assembliesDir = "your_directory"; 
        Assembly asm = Assembly.LoadFrom(Path.Combine(assembliesDir, args.Name + ".dll")); 
        return asm; 
    } 
    
  2. Créer un domaine avec vos propres paramètres (en définissant ApplicationBase ou PrivateBinPath propriétés de l'objet AppDomainSetup).

Donc, si vous voulez continuer à travailler dans le domaine actuel vous avez à utiliser la méthode 1.

+0

merci! Vous venez de me sauver, je cherchais une solution comme celle-là, mais je n'ai rien trouvé dans les réponses à d'autres questions. Cela a fait ma journée :) – SwissCoder

+0

J'essaye de charger un assembly using Assembly.Load qui n'est pas dans GAC, qui échoue et l'événement d'AssemblyResolve sera tiré, où j'emploie LoadFrom pour le charger d'un chemin. Maintenant, cet assemblage sera chargé dans le contexte de la charge, alors utilise-t-il maintenant les images de Ngen? Merci pour toute aide – paritosh

Questions connexes