2008-12-09 4 views
26

Disons que nous avons une solution avec la structure suivante:Comment Visual Studio détermine-t-il les éléments à copier dans le répertoire de sortie avec des solutions multi-projets?

  • Project.DAL - couche d'accès aux données, dépend d'une bibliothèque de niveau inférieur, par exemple Oracle.DataAccess w/copie locale = true
  • Project.BLL - couche logique métier, les références Project.DAL comme projet
  • Project.UI - couche d'interface utilisateur, compile à l'exécutable, les références Project.BLL, par défaut projet

Lorsque Project.UI est compilé, VS est assez intelligent pour copier Project.DAL.dll dans le répertoire de sortie, mais il est pas assez intelligent pour comprendre que je voulais Oracle.DataAccess à copier à la sortie répertoire aussi bien pour la distribution aux clients.

Quelqu'un peut-il expliquer pourquoi c'est ainsi? Est-ce parce qu'il voit Oracle.DataAccess dans le GAC et suppose que les clients l'auront aussi dans le GAC? Ce n'est pas un gros problème, mais c'est un peu ennuyeux que chaque fois que j'ajoute une nouvelle référence d'assemblage, je dois me rappeler de la copier localement et ajouter un élément pour la copier dans mon script de construction.

Répondre

25

Oui, Visual Studio copie d'une DLL dans le chemin de sortie dans l'une des deux conditions suivantes:

  1. La DLL est explicitement référence avec CopyLocal = true
  2. La DLL est référencée sans CopyLocal ou implicitement par une autre DLL et n'est pas dans le GAC

la raison pour laquelle il ne sera pas lorsque le fichier copie local référencé est dans GAC, est que lors de la résolution des noms d'assemblage du GAC a le plus avant ité, c'est-à-dire même si vous avez une copie locale (différente), la version du GAC sera utilisée.

Je vous suggère de configurer un répertoire de bibliothèque dans lequel vous placez tous les assemblys externes référencés. Ensuite, vous configurez un script MSBuild automatique sur un ordinateur (ou machine virtuelle) qui n'a pas le fichier Oracle gac'ed (ni Visual Studio installé dans ce but). De cette façon, le fichier sera copié dans la construction, et vous aurez plus de contrôle sur ce qui est fait que lorsque vous utilisez VS.

+3

+ 1 pour mettre en évidence "et n'est pas dans le GAC" ... cela m'a causé une journée de problèmes. –

+0

Prenez garde que la valeur par défaut de CopyLocal (qui est utilisée si CopyLocal n'est pas explicitement spécifié dans le fichier de projet) a été récemment modifiée dans VS 2015 ([connect.microsoft.com] (https://connect.microsoft.com/VisualStudio/ feedback/details/1572417/the-default-setting-pour-la-copie-locale-de-references-is-now-true))! – Andreas

+0

Comment puis-je obtenir un, par exemple. copie de fichier xsd dans le dossier de sortie? Je ne peux pas référencer un fichier xsd directement dans le code. – Johannes

27

Encore une chose.

Lorsque vous ne pas utiliser la DLL référencé dans votre code du tout, il ignore les CopyLocal et ne copiera pas à votre répertoire de sortie.

+16

Ce qui rend les choses ennuyeuses lorsque vous utilisez l'injection de dépendances et que vous ne faites pas directement référence à une implémentation spécifique. Weeee! – kdawg

+0

Y at-il une solution de contournement pour cela? –

+0

@SimonKarlsson Oui, mais c'est un peu sale, voir les réponses: http://stackoverflow.com/a/24828522/249948 et http://stackoverflow.com/a/21055664/249948. J'aimerais voir une meilleure solution aussi. –

15

J'ai eu une situation étrange où même si l'assembly était une référence de projet et était référencé avec "Copy Local" apparaissant comme "True" dans la fenêtre de propriétés de référence, la DLL n'était pas copiée dans le répertoire de sortie. J'avais une version antérieure de la DLL dans le GAC mais je ne voyais pas pourquoi cela devrait empêcher la DLL d'être copiée.

Je trouve que par le déchargement du projet et modifiant manuellement le XML de référence du projet comme suit:

<ProjectReference Include="..\SomeProject.csproj"> 
    <Project>{11111111-1111-1111-1111-111111111111}</Project> 
    <Name>Some Project Name</Name> 
    <Private>True</Private> 
</ProjectReference> 

La DLL a été copié dans le répertoire ouput comme prévu. J'ai trouvé que le simple paramétrage de Copy Local à True dans la fenêtre des propriétés signifiait que l'élément <Private> était complètement absent, mais dans le cas où il était défini sur false, il était présent avec la valeur "False".

+6

Une alternative à l'édition manuelle du fichier .csproj consiste à définir Copy Local sur False, à faire un fichier - Save All, puis à définir Copy Local sur True et à reconstruire le projet. – RenniePet

Questions connexes