11

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

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

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

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

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

据我所知,微软解决这个问题的方法是在 GAC 中为每台开发、测试和生产机器注册每个依赖项。但这是愚蠢和烦人的。我不会费心给出这个选项和有根据的反驳。

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

我希望有企业 .NET 背景的人能站出来提供一些真正的建议。否则,我将不得不在 NAnt 中重写所有构建脚本(不寒而栗)。

谢谢大家。

更新

针对一些评论,以下是我当前项目中该问题的一个实际示例。

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

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

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

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

我希望这能让问题更清楚。如果有任何不清楚的地方,请告诉我。很难描述这种东西。

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

4

1 回答 1

4

我真的很想给你一个更好的答案,但不幸的是,你没有提供足够的关于你的解决方案/项目和依赖项的信息,所以我会尝试给你几个想法,我希望其中一个有用。

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

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

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

我希望这会有所帮助。

于 2013-03-23T23:14:54.173 回答