如何组织带有开源依赖项的开源Visual Studio项目

本文关键字:开源 Visual Studio 项目 依赖 何组织 | 更新日期: 2023-09-27 18:03:41

我已经启动了一个开源的MVC4项目,它使用其他一些开源项目作为依赖项。我已经分叉了另一个项目,并将根据我的需要修改它。我面临的问题是如何保持这些项目相互依赖,但分别维护。但是那些拉我项目的人,也会得到依赖项目吗?

  1. 我可以将其他项目的所有相关代码猛塞到我的存储库中,但这样我就不能对依赖项目的分支做出贡献。我就会成为存储库的一部分。我不想那么做。
  2. 我可以单独维护其他项目,并将*.dll文件复制到我的项目中。并将依赖的dll文件提交到git。这很好,但我失去了同时开发两个项目的能力,以及在调试时进入依赖代码(好吧,也许不是如果copy *)。pdb文件
  3. 与第2点类似,我可以从依赖项目中构建nuget包并将它们添加到我的主项目中-再次,不能同时开发两个项目,需要切换上下文。
  4. 有一个解决方案文件,它结合了来自我的存储库和依赖存储库的项目。在每次构建中,将依赖的dll文件复制到/lib文件夹并提交。这样我就不需要在不同的项目之间切换上下文。但缺点是当其他贡献者git拉我的项目时,他们不会得到依赖的项目,并且解决方案文件可能会被破坏,因为它会引用不在repo中的项目。
在这种情况下,你如何组织你的代码?

如何组织带有开源依赖项的开源Visual Studio项目

通常我使用nuget来处理我所有的依赖项。当我分叉一个项目时,我将把它部署在nuget和符号源上。通过这种方式,您可以毫无问题地进入依赖源。

有关符号源和nuget的更多信息,请参见:创建和发布符号包。要启用符号源调试,请参见http://www.symbolsource.org/Public/Home/VisualStudio.

您还必须记住启用Nuget包还原。

使用此解决方案,您不能修改源代码,但至少可以调试它。

我使用类似于CMake的概念,但完全在Visual Studio中。属性文件有一个相对不为人知的特性,它可以通过解决方案包含进来。这允许你创建一个只包含依赖项路径的文件,包括你可以包含的库并设置相对路径,然后要求人们为你不能/不想包含的其他依赖项设置适当的路径。

只需要一点点工作,它就会变得相当干净,并且非常容易通过TeamCity和其他类似工具实现自动化(每个构建代理都可以设置变量来指示它保持依赖关系的位置)。

对于小的依赖项和那些已经被调整为与我的项目一起工作的依赖项,我在存储库中保留一个存档或松散文件,并使用属性文件来引用它们。其他的有关于在哪里找到它们以及如何编辑路径的说明。

如果您对这种方法感兴趣,我可以更详细地谈一谈。这需要一些工作来弄清楚,因为属性文件并没有被很好地文档化,但是工作得非常整洁。

如果你没有创建循环依赖,下面是一个想法:

  1. 在解决方案

  2. 中添加一个具有唯一名称的新Class Library项目,例如ClassLibrary1
  3. 在项目设置的Build页面,配置Output path为应用输出路径

  4. Build Events页面中,将以下行添加到Post-build event command line块:

    del "$(TargetPath)"
    
  5. 重复步骤1到3,但要使用另一个名称,例如ClassLibrary2,并将Output path配置为ClassLibrary1的源路径

  6. 设置ClassLibrary1Project Dependancies,检查ClassLibrary2

  7. 将所有其他项目添加为项目参考ClassLibrary2,使Copy Local保持默认值true

  8. 构建ClassLibrary2一次,所有dll现在都在ClassLibrary1的源路径

  9. 将它们添加到ClassLibrary1的引用中,Copy Local保持默认值true

  10. 设置应用程序和所有其他项目的Project Dependancies不导致循环依赖,检查ClassLibrary1

  11. 添加其他项目的引用,从dll存放路径ClassLibrary1

  12. 将其他项目中添加的dll的Copy Local设置为false

因此,项目ClassLibrary1是您的解决方案的外部库的中心控制。每次Rebuild Solution(或者只是构建应用程序)时,ClassLibrary1都会将添加到其引用中的最新DLL复制到应用程序输出文件夹中,并删除它自己生成的名为ClassLibrary1.DLL的DLL。编译时或运行时的应用程序和依赖项将使用相同版本的dll,因此不需要进行额外的部署或检查每个部署。