通过 dll 引用而不是 VS 中的项目引用来管理 .NET 程序集依赖项
Posted
技术标签:
【中文标题】通过 dll 引用而不是 VS 中的项目引用来管理 .NET 程序集依赖项【英文标题】:Managing .NET assembly dependencies by dll reference rather than by project reference in VS 【发布时间】:2010-12-14 14:35:05 【问题描述】:我们有一个由多个子项目(大约 20 个)组成的 .NET 项目。有几个解决方案,每个解决方案只包含与特定解决方案相关的子项目。
为了允许任意解决方案,我们的子项目从不通过项目引用相互引用,而是通过直接 dll 引用。对 csproj 文件进行了少许调整,以使 HintPath 包含 $(Configuration),因此 Debug 构建参考 Debug dll,Release 构建参考 Release dll。
一切都很好,但有两个主要问题 - 一个很烦人,另一个很严重:
-
VS 不识别用于依赖计算的 dll 引用。每次添加新项目或引用时,我们都必须使用“项目依赖项”对话框手动指定依赖项。这很烦人。
我们既不使用 Resharper 也不使用 Visual Assist(很棒的工具,但我们不使用它们,这是给定的)。我们喜欢使用标准的“浏览至定义”命令(例如,可从源代码的上下文菜单中获得)。最严重的问题是,如果一个项目使用项目引用引用另一个项目,则它仅适用于跨项目,并且当引用是直接 dll 引用时它不起作用,即使引用的项目包含在解决方案中!这真是太糟糕了,因为它不是导航到源,而是导航到元数据。
我正在寻求那些像我们一样使用 dll 引用并以某种方式克服这两个问题的人的建议。 谢谢。
编辑:
请注意,除了“浏览至定义”问题之外,使用 Dll 引用而不是项目引用只会给项目经理带来一次成本——即在添加新项目时更新每个受影响解决方案的项目依赖项或必须引入新的依赖项。这些项目依赖项保存在 .sln 文件中,并且在新项目到来或创建新依赖项之前不需要任何维护,这种情况并不经常发生。
我们使用 msbuild 在 CI 服务器上构建我们的项目,它使用与 VS 相同的 .sln 文件。有一个主 .sln 文件,其中包含所有子项目。
我想强调一个更严重的问题 - 无法浏览到另一个项目中的定义,尽管两个项目都在同一个解决方案中,只是因为引用是 dll 引用。这很烦人,也很烦人,VS 没有理由坚持使用项目引用来启用该功能。其他工具,如 Resharper 或 Visual Assist 没有此限制。唉,我们没有这些工具,而且在可观察的未来也不太可能拥有。
【问题讨论】:
只是为了确保我理解,您有一个包含一个或多个项目的解决方案。其中一些项目引用了解决方案中其他项目的 dll 输出,即使引用的项目在解决方案中? 确实如此。但也有其他解决方案,其中不包括一些引用的项目。为了具有这种灵活性,可以随意组合解决方案,我们仅引用 dll。但是,即使涉及的项目都在解决方案中找到,我们也会失去跨项目“浏览到导航”的能力。 是的,我也讨厌这样。一个解决方案真的很棒。 【参考方案1】:您的构建配置存在以下问题:假设您有 3 个项目和 2 个解决方案。
Solution1
- Project1
- Project2
Solution2
- Project1
- Project3
突然之间,构建解决方案 2 会构建解决方案 1 的部分代码,使其处于无效状态(最新的二进制文件要么不兼容,要么不需要构建)。
每个项目都应包含在一个解决方案中。其他解决方案可以依赖,但不应主动更改这些项目的代码。通过这种方式,他们可以引用构建的 DLL,因为没有理由重新构建外部依赖项。
总而言之,您应该花一些时间重新构建您的解决方案以满足以下条件:
每个项目都包含在一个解决方案中。 如果一个项目依赖于同一解决方案中的另一个项目,请将其作为项目引用。 如果一个项目依赖于不同解决方案中的另一个项目,请将其设为 DLL 引用。除了上述之外,我建议创建一个“外部”目录,以便在其他解决方案引用构建时将其放入其中。假设您重组为以下内容:
Solution1
- Project1
- Project2 -> reference project Project1
Solution2
- Project3 -> reference Project1.dll
在这种情况下,您需要将 Project1.dll 和 Project1.pdb 的副本放在 Externals\Project1\Debug
和 Externals\Project1\Release
中,并在 Project3 中引用 External\Project1\$(Configuration)\Project1.dll
。仅当您准备好将构建推送到所有其他解决方案时,才更新 Externals 目录中的构建。
【讨论】:
好的,请多多指教。添加到上面:如何管理已发布 Project.dll 的版本控制?我希望 Project3 从版本控制中选择 Project1.dll。【参考方案2】:您是否有任何理由要允许任意解决方案?似乎更容易创建一个解决方案并将所有项目放入该解决方案中。我尽量避免使用多种解决方案。
【讨论】:
项目越多加载时间越长,而且在构建时会检查所有项目,如果主要部分未更改,则开销太大。 UI 开发人员可能永远不会接触一半的项目,那么为什么要支付每次构建的成本,再加上加载解决方案的一次成本呢?【参考方案3】:在我看来,您遇到的问题是错误使用工具集的直接结果。当您不让 Visual Studio 管理项目依赖项时,它没有其他方法可以自动计算项目依赖项。
听起来你有两个选择。
-
使用 Visual Studio 管理项目依赖项
使用其他构建系统(如 NAnt)
听起来你已经排除了选项#1,所以我不会再讨论这个问题了。所以只剩下选项#2。
您可以使用NAnt 来构建您的个人 CSproj 项目,并使用您的 NAnt 构建脚本来定义项目之间的依赖关系。这样做有两个缺点。
-
你必须管理所有的买手(听起来你准备这样做)
Visual Studio 对您来说会和现在一样破碎。
在缺点 #2 方面,Visual Studio 将无法将您的解决方案作为一个整体进行编译,因为该逻辑已从 VS 转移到外部构建脚本中。这可能会导致开发人员之间的混淆,并会阻碍调试过程。并不是说这些事情是无法克服的……只是说在开发过程的这些步骤中会涉及额外的设置。
【讨论】:
我不明白 Nant 给了我什么,而不是 msbuild。我们的项目是在 CI 服务器上使用 msbuild 构建的,并且运行良好。唯一的问题是 .sln 文件(msbuild 和 VS 都使用)必须明确包含项目依赖项,因为我们引用的是 Dll 而不是项目。就这样。我不明白为什么要切换到 NAnt。以上是关于通过 dll 引用而不是 VS 中的项目引用来管理 .NET 程序集依赖项的主要内容,如果未能解决你的问题,请参考以下文章
请教C#/.net高手,用VS结合源码管理团队协作开发,如何处理引用的dll在不同机器路径不一样的问题?