如何在Visual Studio/MSBuild中进行依赖项管理

Viv*_*ell 11 msbuild dependency-management visual-studio

关于这个主题有很多帖子,但我还没有找到"真正的"解决方案.

如何使用MSBuild项目文件(即通过项目和文件引用的Visual Studio项目文件)管理其依赖树(编译时和运行时)?

众所周知,如果没有编译时引用,即使存在运行时依赖项,即使copy-local = true,也不会将子项目中的项目引用复制到应用程序bin目录.因此,任何松散耦合的组件都不会被复制.

解决此问题的方法是使用copy-local = true在父项目中包含依赖项.但是,这基本上会破坏你的依赖树,因为你不再知道依赖关系在哪里,最终,随着你的应用程序的增长和变形,你最终会得到一个DLL版本的地狱.您的父项目最终会有10到100个dll,其中大多数是子项目中dll的运行时依赖项.

另一个黑客是编写自定义目标文件并从每个项目文件中调用它:http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html.但肯定有更好的选择.这是一种面包和黄油的东西.Java开发人员永远不必处理这些微不足道的问题.

从我可以收集的信息来看,Microsoft解决此问题的方法是在每个开发,测试和生产机器中注册GAC中的每个依赖项.但这是愚蠢而烦人的.我不会费心给出这个选项并接受教育的反驳.

避免使用GAC选项,如何使用MSBuild来管理包含仅运行时依赖项的依赖关系树?微软是如何做到的?当然,他们不会运行上面链接中的自定义目标文件.

我希望来自企业.NET背景的人可以加强并提供一些真正的建议.否则我只需要在NAnt(shudder)中重写我的所有构建脚本.

谢谢大家.

UPDATE

在回答一些评论时,以下是我当前项目中问题的一个实际例子.

该应用程序是一个Web应用程序项目,它公开了一套WCF服务.它有一个包含外部服务类的外部域DLL和一个包含内部服务POCO,域对象和DAO的内部域DLL.有一个单独的集成DLL,包含所有内部域类的接口(DTO),允许我们完全解耦外部域和内部域.整个事情与Spring.net联系在一起.我希望这很清楚,如果您需要更多说明,请告诉我.

我当前的构建过程是使用MSBuild为Web应用程序生成部署包(在TFS Build中).因此,虽然最初构建整个解决方案,但只有Web应用程序的输出被打包.因此,Web应用程序被视为依赖根,我希望任何松散耦合的子引用都应该在构建时复制,如果它们设置为'copy-always = true'.

因此,Web应用程序包含对外部域DLL的引用,该DLL包含对内部域DLL的引用,其中包含对第三方库的许多引用以及第三方库所需的各种间接和松散耦合的依赖项.

当内部域DLL中存在第三方依赖时,例如在运行时NHibernate需要的oracle.dataaccess时,会出现此问题.即使我在这些DLL上设置'copy-always = true',它们也不会被复制到Web App包中.我可以将它们包含在包中的唯一方法是将这些DLL添加到Web App的引用中.我不想这样做,因为我不再有一个有意义的依赖树.

我希望这会使问题更加清晰.如果有任何不清楚的地方,请告诉我.很难描述这种东西.

如果有人也有类似的问题,请说出来并分享您的经验.

Bis*_* C. 4

我真的很想给您一个更好的答案,但不幸的是您没有提供有关您的解决方案/项目和依赖项的足够信息,因此我将尝试为您提供一些想法,我希望其中之一可行。

  1. 正如您所说,最简单的事情是设置一个包含所有依赖项的单独文件夹,并创建目标文件,将它们复制到您的 bin 文件夹中。如果您的依赖项不经常更改,那么这可能会起作用。如果您公司的另一个团队正在构建它们并且它们经常变化,那么这种方法并不好。

  2. 另一种简单的方法 - 如果您从解决方案中引用依赖项,则只有您可以更改构建路径,以便它们直接构建到主项目的 bin 文件夹中。这样您就不必直接引用它们。

  3. 使用 NuGet。您有一个单独的团队生成松散耦合的依赖项,设置本地 NuGet 存储库并将其用于http://juristr.com/blog/2012/04/using-nuget-to-distribute-our-company可能是有意义的/

我希望这有帮助。