关于这个主题有很多帖子,但我还没有找到“真正的”解决方案。
如何使用 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 应用程序的引用中。我不想这样做,因为我不再有一个有意义的依赖树。
我希望这能让问题更清楚。如果有任何不清楚的地方,请告诉我。很难描述这种东西。
如果有人也有类似的问题,请说出来并分享您的经验。