【问题标题】:Can NuGet use per-project package download paths within the same solution?NuGet 可以在同一解决方案中使用每个项目的包下载路径吗?
【发布时间】:2015-05-20 19:42:35
【问题描述】:

为我们的解决方案考虑这个 repo/文件结构...

Shared Repo (Checked out to D:/Shared/trunk)
    ├───Shared1.dll Project
    └───Shared2.dll Project

App1 Repo (Checked out to C:/Code/App1/Trunk)
    ├───App1 Project (Refs Shared1.dll project)
    ├───App1.dll Project (Refs Shared1.dll and Shared2.dll projects)
    └───App1.sln

App2 Repo (Checked out to C:/Code/App2/Trunk)
    ├───App2 Project (Refs Shared1.dll project)
    ├───App2a.dll Project (Refs Shared1.dll and Shared2.dll projects)
    ├───App2b.dll Project (Refs Shared1.dll and App2a.dll projects)
    └───App2.sln

为了更轻松地处理代码,我们将共享项目直接引入到应用程序的解决方案中,例如,如果您打开 App1.sln,这将是您的项目树...

App1.sln
    ├───Shared1.dll Project
    ├───Shared2.dll Project
    ├───App1 Project (Refs Shared1.dll project)
    └───App1.dll Project (Refs Shared1.dll and Shared2.dll projects)

如您所见,这两个共享 DLL 来自一个单独的存储库,但包含在此解决方案中。 Visual Studio 可以毫无问题地处理此问题,当您针对解决方案执行提交时会提示您正在更新多个存储库。这很好,正是我们想要的。

然而,我们遇到的问题是 NuGet。据我们了解,NuGet.config(以及读取/应用它们的层次结构/优先级)与解决方案文件相关,因此项目的 NuGet 引用会相应更新。当您在 App1.sln 中工作时,这会导致对 Shared1.dll 和 Shared2.dll 中 NuGet 包的引用相对于 App1.sln 的问题,这意味着如果其他人在 App2.sln 中工作并且尚未检查以完全相同的方式将它们的两个树干彼此相对,引用中断。

我们的解决方法是始终将所有三个主干作为同级检出到同一个文件夹中,然后将打包文件夹作为另一个同级,在每个解决方案旁边的 NuGet.config 中添加“../packages”。这可以确保引用永远不会中断,但会强制结帐的位置,这可能是一个问题。

C:/Code/
    ├───Shared Trunk
    ├───App1 Trunk
    ├───App2 Trunk
    └───packages

但是,如果我们可以指定每个项目的包下载位置,我们可以将打包文件夹放置在与项目本身相关的位置,这意味着您将它们检出到哪里都无关紧要。他们总能找到他们需要的包裹。是的,这意味着在我们的示例中,会有重复的包下载,但磁盘空间不是问题。维护代码是。

C:/Code/
    ├───Shared Trunk
    │    └─sharedpackages
    ├───App1 Trunk
    │    └─app1packages
    └───App2 Trunk
         └─app2packages

同样,我们想要的是在打开 App1.sln 时,我们希望 Shared1.dll 和 Shared2.dll 的包放在“sharedpackages”文件夹中,但 App1 和 App1.dll 使用的包放在 app1packages 中。

那么……这可能吗?是否可以为每个项目指定不同的 NuGet 包下载路径,而不管它们在哪个解决方案中?

【问题讨论】:

  • 正如您所怀疑的,这是不可能的。 NuGet 当前始终检查与解决方案目录相关的 NuGet.Config 文件。因此,正如您所做的那样,将单独的存储库检出到指定的相对目录可能是唯一的解决方案。
  • 如果您为共享项目创建解决方案,那么您的所有项目都将引用其父级中的 packages 文件夹。然后您可以合并您的应用程序和共享项目,它们都将使用正确的相对引用。
  • 我最初是这么想的,但是当您将它们带回一个解决方案(例如 App1)时,问题就出现了,NuGet 完全搞砸了,不知道从哪里拉东西。更新也不起作用。
  • 嗯..顺便说一句:您使用的是什么 VCS?颠覆、TFS 等?您还可以显示您正在使用的实际文件夹名称,还是名称中实际上有“Trunk”?我要看看我是否能找到解决方案(没有双关语)。
  • 这根本行不通,因为这样做的全部目的是访问 source 代码,这样您就可以在处理应用程序的同时处理这些 DLL .向上看 App1.sln 的结构。它引用 DLL 的项目,而不是 DLL 本身。有意义吗?

标签: visual-studio nuget projects-and-solutions


【解决方案1】:

我和 /u/MarquelV 的情况一样。

从我对 nuget 提供的用于处理这种情况的选项(至少到 3.5 版)的调查来看,我得出的结论是,必须完全忽略 Visual Studio 中用于 nuget 的图形工具(至少到目前为止安装/恢复包)并且还禁用自动包恢复(工具->选项-> Nuget等)。然后在需要安装/恢复包时从命令行调用 nuget.exe 来指定应放置包的文件夹 - 这一点很重要,因为 Visual Studio 中 nuget 的图形界面倾向于将包存储在“全局”存储库(通常位于解决方案的 .sln 文件旁边)。

在我的项目中,我在每个项目中创建了一个 .nuget 文件夹和 nuget.exe,并因此引用 dll。

最后但并非最不重要的一点是,每个项目都需要通过 .csproj 使用 nuget 来恢复包,如下所示:

 <Target Name="BeforeBuild">
      <Exec Command=".\.nuget\nuget.exe restore  .\packages.config -PackagesDirectory .\packages"/>
 </Target>

要消除这一切的是,不能依赖用于 nuget 的图形工具和自动包恢复(工具 -> 选项 -> Nuget)来实现此处描述的目标。

【讨论】:

  • 我喜欢你的“BeforeBuild”解决方案。不像你说的那样完全符合我的要求,你现在不能使用图形工具,所以不能从命令行修改包,但仍然是这样,所以我要把它标记为回答。 (无论如何,它现在已经过时了。:)
【解决方案2】:

我最近遇到了类似的问题。就我而言,我将较小解决方案的项目组合成一个较大的解决方案。这些项目仍在引用其子文件夹中的包,我不想更改这些引用并破坏较小的解决方案。我能够通过将项目包路径符号链接到解决方案级路径来解决它。

mklink /J .\packages ..\packages

这有效地诱使项目认为它使用的是更本地化的包版本,而实际上它使用的是更大解决方案中的包。

情况并不完全相同,但足够接近,我希望它可以帮助某人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    相关资源
    最近更新 更多