"Copy Local"和项目引用的最佳实践是什么?

164

我有一个庞大的C#解决方案文件(约100个项目),希望提高构建时间。我认为在很多情况下,“复制本地”是浪费的,但我想知道最佳实践。

在我们的 .sln 中,应用程序A依赖于程序集B,而程序集B依赖于程序集C。在我们的情况下,有数十个“B”和少量的“C”。由于这些都包含在 .sln 中,我们使用项目引用。所有程序集当前都构建到 $(SolutionDir)/Debug(或 Release)中。

默认情况下,Visual Studio将这些项目引用标记为“复制本地”,这会导致每个正在构建的“B”都会将每个“C”复制一次到 $(SolutionDir)/Debug 中。这似乎很浪费。如果我只是关闭“复制本地”,会出现什么问题?其他大型系统的用户怎么做?

后续:

许多回复建议将构建分成较小的 .sln 文件......在上面的示例中,我首先构建基础类“C”,然后是大部分模块“B”,最后是一些应用程序“ A”。在这种模式下,我需要从 B 到 C 进行非项目引用。我遇到的问题是“Debug”或“Release”被烘焙进了提示路径中,导致我构建 B 的 Release 版本时对 C 的调试版本进行了构建。

对于那些将构建拆分为多个 .sln 文件的人,你们是如何解决这个问题的?


9
通过直接编辑项目文件,您可以使提示路径参考 Debug 或 Release 目录。 使用 $(Configuration) 代替 Debug 或 Release。例如,<HintPath>..\output$(Configuration)\test.dll</HintPath>如果有很多引用,这将很麻烦(尽管应该不难编写插件来管理此过程)。 - ultravelocity
5
在Visual Studio中,“Copy Local”与csproj中的“<Private>True</Private>”是否相同? - Colonel Panic
但是将一个“.sln”拆分成较小的项目会破坏VS对“<ProjectReference/>”的自动依赖项计算。我自己从多个较小的“.sln”转移到单个大的“.sln”,只是因为这样做VS会更少出问题...所以,也许后续问题假设了不一定是最佳解决方案的原始问题?;-) - binki
1
@ColonelPanic 是的。至少在我更改GUI中的切换时,磁盘上的内容会发生变化。 - Zero3
18个回答

1

我倾向于构建到一个公共目录(例如..\bin),这样我就可以创建小型测试解决方案。


1
你可以尝试使用一个文件夹,将所有在项目之间共享的程序集复制到其中,然后设置一个DEVPATH环境变量,并在每个开发人员的工作站上在machine.config文件中设置

<developmentMode developerInstallation="true" />

你需要做的唯一事情就是将任何新版本复制到DEVPATH变量指向的文件夹中。

如果可能的话,还可以将解决方案分成几个较小的解决方案。

有趣...这在调试和发布版本中如何运作? - Dave Moore
我不确定是否存在适合通过DEVPATH加载调试/发布程序集的解决方案,它仅用于共享程序集,不建议用于常规构建。 另外,请注意,使用此技术时,程序集版本和GAC将被覆盖。 - Aleksandar

1

这可能不是最佳实践,但这是我的工作方式。

我注意到Managed C++将其所有二进制文件都转储到$(SolutionDir)/'DebugOrRelease'中。 因此,我也将所有的C#项目都转储到那里。我还关闭了解决方案中所有引用到项目的“复制本地”选项。在我的小型10个项目的解决方案中,我有明显的构建时间改善。该解决方案是C#、托管C++、本机C++、C# Web服务和安装程序项目的混合。

也许有些东西出了问题,但由于这是我唯一的工作方式,所以我没有注意到它。

找出我正在破坏什么将是有趣的。


0
如果引用不包含在GAC中,我们必须将Copy Local设置为true,以便应用程序可以工作;如果我们确定引用将预安装在GAC中,则可以将其设置为false。

0

0

嗯,我确实不知道问题是如何解决的,但我接触过一种构建解决方案,它通过使用符号链接将所有创建的文件放在ramdisk上来帮助自己。

  • c:\solution folder\bin -> ramdisk r:\solution folder\bin\
  • c:\solution folder\obj -> ramdisk r:\solution folder\obj\

  • 您还可以告诉Visual Studio可以用于构建的临时目录。

实际上,这并不是它所做的全部。但它确实打破了我的性能理解。
100%的处理器使用率和一个包含所有依赖项的大型项目在不到3分钟内完成。


0
通常情况下,只有在您希望项目使用位于Bin中的DLL而不是其他位置(如GAC、其他项目等)时,才需要复制本地。
我倾向于同意其他人的观点,如果可能的话,也应该尝试将解决方案分解。
您还可以使用配置管理器在一个解决方案中创建不同的构建配置,这些配置将仅构建给定的一组项目。
如果所有100个项目都相互依赖,那么似乎很奇怪,因此您应该能够将其分解或使用配置管理器来帮助自己。

0

你可以将项目引用指向dll的调试版本。 然后在你的msbuild脚本中,你可以设置/p:Configuration=Release,这样你就会得到一个应用程序和所有卫星程序集的发布版本。


1
Bruno - 是的,这适用于项目引用,这也是我们第一次使用100个项目解决方案的原因之一。但是它不适用于我浏览到预构建的Debug版本的引用 - 我最终会得到一个针对Debug程序集构建的Release应用程序,这是一个问题。 - Dave Moore
4
在文本编辑器中编辑您的项目文件,并在HintPath中使用$(Configuration),例如: <HintPath>..\output$(Configuration)\test.dll</HintPath>。 - ultravelocity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接