IS"复制本地"传递的项目参考? [英] Is "Copy Local" transitive for project references?

查看:181
本文介绍了IS"复制本地"传递的项目参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

WRT。所提出的重复数据删除:由于这这里queston暗示的相反的<一个href="http://stackoverflow.com/questions/12386523/visual-studio-not-copying-content-files-from-indirectly-referenced-project">linked问题,我宁愿这样想是的没有的一个傻瓜。

第一,我读过<一个href="http://stackoverflow.com/questions/280751/what-is-the-best-practice-for-copy-local-and-with-project-references">What对于复制本地和与项目引用的最佳实践?(也<一href="http://stackoverflow.com/questions/602765/when-should-copy-local-be-set-to-true-and-when-should-it-not">this)我将不得不尝试了这一点,无论如何,但得到这个通用的反馈似乎是必要的的文档对这个东西是可怕的,我只在VS2010,也许他们改变了一些较新的版本会是很好的了解。

,我只关心的项目引用的这个问题,因为我已经的read~~V从GAC组件的处理方式不同和GAC无关我的问题。

第三,阅读建议的欺骗,但更漂亮回答这里由后@Albireo,它也将出现,它区分的文件的相关性,是非常重要的,其中的依赖引用一个DLL组件文件和项目的相关性(即什么我问) ,其中,依赖一个引用的项目的与该项目的隐含输出文件。

不管怎么说,这里的情况,有点特殊,我认为,但还是:

  • 2 C#可执行项目
  • ňC#DLL组件项目
  • 的2可执行文件有不同的输出目录,因为他们将分别部署这样他们也分开开发机器上
  • 的2可执行文件对某些DLL组件的依赖关系(可能互相依赖的)
  • 有三种输出目录:
    • / X1 可执行1个项目
    • / X2 可执行2项目
    • / lib目录所有DLL组件

该DLL组件的所有的有无复制本地设置为为他们的项目引用,因为它们都建立在同一输出目录。

2. 可执行项目设置复制本地 所有他们直接引用,这样的DLL将被复制到 / X1 / X2 分别。

问题现在WRT。到的DLL是的没有的直接可执行的项目中引用,但是的只有的传递性地通过引用的程序集:请问集会,这是的只有的通过另一个组件传递性地引用,复制到可执行文件的输出文件夹,在复制本地的的设置为true的第一个组件?

例如:

  • x1.csproj (egOutput = X1 / one.exe
    • 参考: dlA.csproj (如输出= 的lib / A.DLL )使用复制本地= *真*
    • (上B.DLL没有直接提到)
  • dlA.csproj (如输出= 的lib / A.DLL
    • 参考: dlB.csproj (如输出= 的lib / B.DLL )使用复制本地= **假**
    • (上c.dll没有直接提到)
  • dlC.csproj (如输出= 的lib / c.dll
    • (没有进一步的相关参考资料)

因此​​,我们有 one.exe逻辑依赖 - &GT; A.DLL - &GT; B.DLL - &GT; c.dll ,其中只有 A.DLL 有明显被复制到输出目录 one.exe ,对其他两个DLL也被复制到输出目录? 这个记录的地方?


和,是的,我试了一下。而且,是的,它的似乎的工作,但我还没有戳难还不够,反正有可能更多的东西给它,我可能已经错过了。 (也有问题WRT。任何官方的文档。)

解决方案
  

这也似乎它区分文件相关性,是非常重要的,其中的依赖引用一个DLL组件文件和项目的依赖关系(即什么我问),其中,依赖引用一个项目,那隐含的输出文件项目。

不是真的,没有。

的MSBuild并不真正关心的参考点到另一个项目的解决方案或一个DLL。

如果项目A 依赖于项目B 来建立项目A 项目B 必须已经建立(最多最新的),的MSBuild然后将其拉DLL(而不是它的C#code),并将其链接到项目A

添加一个项目引用,而不是一个DLL是语法糖为了您的方便。这样的MSBuild知道它必须选择引用的项目的输出,无论输出为

否则,您必须手动pre-打造的依赖,找到它的DLL,并将其链接到项目,重复上述过程,当切换构建配置,移动或重命名的东西。不是真的实用。

  

,对其他两个DLL也被复制到输出目录?

如果从一个依赖任何一种元素是直接从所在的组件中引用的项目中使用,该引用将被复制。

要更好地说明我创建了一个样品溶液和其托管在GitHub上的问题,你可以在<一个发现href="https://github.com/kappa7194/msbuild-dependency-test">https://github.com/kappa7194/msbuild-dependency-test

该解决方案的布局是:

  • MySolution
    • MySolution.ConsoleApplication
    • MySolution.FirstDependency
    • MySolution.SecondDependency
    • MySolution.ThirdDependency
    • MySolution.FourthDependency

依赖链是:

  • MySolution.ConsoleApplication
    • MySolution.FirstDependency
      • MySolution.SecondDependency
        • MySolution.ThirdDependency
        • MySolution.FourthDependency

如果您构建此解决方案,你会发现,在 MySolution.ConsoleApplication 输出目录会有的DLL文件 MySolution.FirstDependency MySolution.SecondDependency MySolution.ThirdDependency ,但没有DLL的 MySolution。 FourthDependency

为什么会这样呢? 当MSBuild的构建 MySolution.SecondDependency 它注意到有声明 MySolution.FourthDependency 的依赖,但由于它找不到任何一种元素,从 MySolution.FourthDependency MySolution.SecondDependency code的任何用途决定执行一些优化,省略了 MySolution.FourthDependency 组装的从输出。

这同样的问题咬了我的过去,当我经过的NuGet AutoMapper添加到深依赖:将AutoMapper增加了两个程序集引用, AutoMapper AutoMapper.Net4 ,其中第二个组件是由第一次加载通过反射时,它需要由.NET Framework 4中引入由于第二组件的新的集合对象执行特定的动作通过反射的MSBuild认为这是不使用的,不会打扰到周围的复制加载。

因此,的,他们将只要你使用它们直接复制并没有通过反射。

  

这是记载地方?

此行​​为似乎是的MSBuild的功能,我设法发现一些人从微软博客中回来时,我遇到过这个问题,但我不能再次找到它的时刻。

Wrt. the proposed dupe: Since this here queston suggests the opposite of the linked question, I'd rather like to think it is not a dupe.

First, I did read What is the best practice for "Copy Local" and with project references? (also this) and I'll have to try this out anyway, but getting general feedback on this seems necessary as the docs on this stuff are horrible and I'm only on VS2010 and maybe they changed something in newer versions that'll be nice to know.

Second, I'm only interested in project references for this question as I've read that assemblies from the GAC are handled differently and the GAC is irrelevant for my problem.

Third, after reading the suggested dupe, but more so the nice answer here by @Albireo, it would also appear that it is important to differentiate file dependencies, where the dependency references a dll assembly file and project dependencies (i.e. what I'm asking about), where the dependency references a project and implicitly the output file of that project.

Anyway, here's the situation, somewhat peculiar I think, but still:

  • 2 C# executable projects
  • n C# dll assembly projects
  • The 2 executables have different output directories as they will be deployed separately and that way they're also separate on the developer machine
  • The 2 executables have dependencies on some of the DLL assemblies (which may depend on each other)
  • There are three output directories:
    • /x1 for executable 1 project
    • /x2 for executable 2 project
    • /lib for all the dll assemblies

The DLL assemblies all have Copy Localset to false for their project references, as they all build to the same output directory.

The 2 executable projects have set Copy Local to true for all the DLL assembly project references they reference directly, so that the DLLs will be copied into /x1 /x2 respectively.

The question now is wrt. to DLLs that are not directly referenced by an executable project, but only transitively through a referenced assembly: Will assemblies, that are only referenced transitively through another assembly, be copied into the output folder of the executable, when "Copy Local" is set to true on the first assembly?

Example:

  • x1.csproj (e.g.Output = x1/one.exe)
    • Reference: dlA.csproj ( e.g. Output = lib/a.dll) with Copy Local = *true*
    • (no direct reference on b.dll)
  • dlA.csproj ( e.g. Output = lib/a.dll)
    • Reference: dlB.csproj ( e.g. Output = lib/b.dll) with Copy Local = **false**
    • (no direct reference on c.dll)
  • dlC.csproj ( e.g. Output = lib/c.dll)
    • (no further relevant references)

Thus, we have a logical dependency of one.exe -> a.dll -> b.dll -> c.dll, where only a.dll with obviously be copied to the output directory of one.exe. Will the other two dlls also be copied to the output directory? Is this documented somewhere?


And, yes, I tried it. And, yes, it seems to work, but I haven't poked it hard enough yet and anyway there maybe something more to it that I may have missed. (And also there's the question wrt. any official docs.)

解决方案

it would also appear that it is important to differentiate file dependencies, where the dependency references a dll assembly file and project dependencies (i.e. what I'm asking about), where the dependency references a project and implicitly the output file of that project.

Not really, no.

MSBuild doesn't really care if the reference points to another project in the solution or to a DLL.

If ProjectA depends on ProjectB to build ProjectA ProjectB must be already built (and up-to-date), MSBuild will then pull its DLL (not its C# code) and link it to ProjectA.

Adding a project reference instead of a DLL is "syntactic sugar" for your convenience: this way MSBuild knows it must pick the output of the referenced project, whatever the output is.

Otherwise, you'll have to manually pre-build the dependency, find its DLL and link it to the project, repeating the process whenever you switch build configuration, move or rename things. Not really practical.

Will the other two dlls also be copied to the output directory?

If any kind of element from a dependency is used directly from the project where the assembly is referenced, that reference will be copied.

To better illustrate the issue I created a sample solution and hosted it on GitHub, you can find it at https://github.com/kappa7194/msbuild-dependency-test

The solution layout is:

  • MySolution
    • MySolution.ConsoleApplication
    • MySolution.FirstDependency
    • MySolution.SecondDependency
    • MySolution.ThirdDependency
    • MySolution.FourthDependency

The dependency chain is:

  • MySolution.ConsoleApplication
    • MySolution.FirstDependency
      • MySolution.SecondDependency
        • MySolution.ThirdDependency
        • MySolution.FourthDependency

If you build this solution you'll notice that in MySolution.ConsoleApplication output directory there will be the DLLs for MySolution.FirstDependency, MySolution.SecondDependency and MySolution.ThirdDependency but no DLL for MySolution.FourthDependency.

Why is it so? When MSBuild builds MySolution.SecondDependency it notices that there's a dependency declared to MySolution.FourthDependency, but since it can't find any usage of any kind of element from MySolution.FourthDependency in MySolution.SecondDependency code it decides to perform some "optimization" and omits MySolution.FourthDependency assembly from the output.

This same issue bit me in the past when I added through NuGet AutoMapper to a "deep dependency": adding AutoMapper adds two assembly references, AutoMapper and AutoMapper.Net4, where the second assembly is loaded by the first through reflection when it needs to perform certain kind of action on the new collection objects introduced by the .NET Framework 4. Since the second assembly is loaded through reflection MSBuild thinks it's unused and doesn't bother to copy it around.

So, yes, they will be copied as long as you're using them directly and not through reflection.

Is this documented somewhere?

This behavior seems to be a "feature" of MSBuild, I managed to found a blog post by some folks from Microsoft back when I experienced this issue, but I can't find it again at the moment.

这篇关于IS&QUOT;复制本地&QUOT;传递的项目参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆