在这个主题上有很多帖子,但我还没有找到“真正的”解决方案。如何在Visual Studio/MSBuild中执行依赖关系管理
如何使用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中的所有构建脚本(不寒而栗)。
谢谢大家。
UPDATE
在回应一些评论,以下是从我的当前项目问题的一个实际的例子。
该应用程序是一个Web应用程序项目,公开了一套WCF服务。它具有包含外部服务类的外部域DLL以及包含内部服务POCO,域对象和DAO的内部域DLL。有一个单独的集成DLL包含所有内部域类的接口(DTO),这些接口允许我们完全分离外部和内部域。整个事情与Spring.net联系在一起。我希望这是清楚的,让我知道你是否需要更多的澄清。
我目前的构建过程是使用MSBuild为Web应用程序(在TFS Build中)生成部署包。因此,尽管整个解决方案是最初构建的,但只有来自Web应用程序的输出才能打包。因此,Web应用程序被视为依赖项根,并且我期望任何松散耦合的子引用应该在构建时拷贝过来,如果它们被设置为'copy-always = true'的话。
因此,Web应用程序包含对外部域DLL的引用,其中包含对内部域DLL的引用,其中包含对第三方库的许多引用以及第三方库所需的各种间接和松散耦合的依赖关系。
当内部域DLL中存在第三方依赖关系时会出现问题,例如在运行时NHibernate需要的oracle.dataaccess。即使在这些DLL上设置'copy-always = true',它们也不会被复制到Web App包中。我可以将它们包含在包中的唯一方法是将这些DLL添加到Web应用程序的引用中。我不想这样做,因为我不再有一个有意义的依赖关系树。
我希望这可以让问题更清楚。请让我知道,如果有什么不清楚。很难形容这种东西。
如果有人也有类似的问题,请说出来,分享您的经验。
是的,我同意你将它们添加到GAC的效率会很低,但我只是好奇NAnt在这种情况下会如何帮助你更多?另外在Java开发中如何处理这种情况?我想更多的线索,以便我可以给你更好的答案...谢谢 –
我认为他想要的东西就像Java中的maven。实际上我也在寻找类似的东西。 http://maven.apache.org/ –
在反思中,我认为NAnt会导致更多的问题。我将用一个具体的问题示例更新原始帖子。 –