通过 dll 引用而不是 VS 中的项目引用来管理 .NET 程序集依赖项
我们有一个由多个子项目(大约 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 则没有此限制。可惜的是,我们没有这些工具,而且在可预见的未来也不太可能拥有这些工具。
We have a .NET project consisting of multiple subprojects (around 20). There are several solutions, each containing only those subprojects which are relevant to the particular solution.
To allow for arbitrary solutions, our subprojects never reference each other by means of project references, but rather by direct dll references. There is little tweaking of the csproj file, to make HintPath include $(Configuration), so Debug builds reference Debug dlls and Release builds reference Release dlls.
All works great, but there are two major problems - one is annoying and another is really acute:
- VS does not recognize dll references for the purpose of the dependency calculation. We have to manually specify the dependencies using the "Project Dependencies" dialog each time a new project or reference is added. This is annoying.
- We use neither Resharper nor Visual Assist (great tools, but we do not use them, it's a given). We do like to use the standard "Browse to Definition" command (available from the context menu on the source code, for instance). The acute problem is that it only works cross project if one project references the other using the project reference and it does not work when the reference is the direct dll reference, even if the referenced project is included in the solution! That's a real bummer, because instead of navigating to the source it navigates to the metadata.
I am seeking for an advice of those folks out there who use dll references like us and have somehow overcome these two issues.
Thanks.
EDIT:
Note, that besides the "Browse to Definition" issue, having Dll references instead of project references incurs only one time cost on the project manager - which is to update the project dependencies of each affected solution when a new project is added or a new dependency must be introduced. These project dependencies are persisted in the .sln file and do not require any maintenance until a new project arrives or a new dependency is created, which happens not that too often.
We are using msbuild for building our projects on the CI server, which uses the same .sln files as VS does. There is one main .sln file, which includes all the subprojects.
I wish to emphasize the more acute problem - the inability to browse to a defintion in another project, although both projects are in the same solution just because the references are dll references. This is annoying and it is a nuisance, there is no reason why VS insists on project references to enable the feature. Other tools, like Resharper or Visual Assist do not have this limitation. Alas, we do not have these tools and unlikely to have in the observable future.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的构建配置问题如下:假设您有 3 个项目和 2 个解决方案。
突然间,构建 Solution2 会构建 Solution1 的部分代码,使其处于无效状态(最新的二进制文件要么不兼容,要么不需要构建)。
每个项目都应该包含在一个解决方案中。其他解决方案可以依赖,但不应主动更改这些项目的代码。通过这种方式,他们可以引用构建的 DLL,因为没有理由重建外部依赖项。
总而言之,您应该花一些时间重组您的解决方案以满足以下条件:
除了上述内容之外,我建议创建一个“Externals”目录,以便在其他解决方案引用它们时放置构建。假设您重组为以下内容:
在这种情况下,您将 Project1.dll 和 Project1.pdb 的副本放置在
Externals\Project1\Debug
和Externals\Project1\Release
中,并在 Project3 中引用External\Project1\$(Configuration)\Project1.dll
。仅当您准备好将构建推送到所有其他解决方案时,才更新外部目录中的构建。The problem with your build configuration is the following: say you have 3 projects and 2 solutions.
All of a sudden, building Solution2 builds part of the code for Solution1, leaving it in an invalid state (the latest binaries are either incompatible or did not need to be built).
Every project should be included in a single solution. Other solutions can rely on, but should not actively change the code of those projects. In this way, they can reference a built DLL because there's no reason to rebuild the external dependencies.
To summarize, you should take some time and restructure your solutions to meet the following conditions:
In addition to the above, I recommend creating an "Externals" directory for placing builds in when they are referenced by other solutions. Say you restructure to the following:
In this case, you'd place copies of Project1.dll and Project1.pdb in
Externals\Project1\Debug
andExternals\Project1\Release
, and referenceExternal\Project1\$(Configuration)\Project1.dll
in Project3. Only update the builds in the Externals directory when you are ready to push the build to all your other solutions.您是否有任何理由想要允许任意解决方案?创建一个解决方案并将所有项目放入该解决方案中似乎会更容易。我尽量避免使用多种解决方案。
Is there any reason why you want to allow for arbitrary solutions? It seems like it would be easier to create a single solution and put all of the projects in that solution. I try to avoid multiple solutions wherever possible.
在我看来,您遇到的问题是不正确使用工具集的直接结果。当您不让 Visual Studio 管理项目依赖项时,它没有其他方法可以自动计算项目依赖项。
听起来你有两个选择。
听起来您已经排除了选项 #1,所以我不会再讨论这个问题。这样就只剩下选项#2了。
您可以使用 NAnt 构建您的个人 CSproj 项目,并使用 NAnt 构建脚本来定义项目之间的依赖关系。这样做有两个缺点。
缺点#2 是,Visual Studio 无法将您的解决方案作为一个整体进行编译,因为该逻辑已从 VS 转移到外部构建脚本中。这可能会导致开发人员感到困惑,并阻碍调试过程。并不是说这些事情无法克服……只是说开发过程的这些步骤需要额外的设置。
It sounds to me like the problems you are encountering are the direct result of using your tool set incorrectly. Visual Studio has no other way of automatically calculating project dependencies when you don't let it manager them.
It sounds like you have two choices.
It sounds like you have ruled out option #1, so I won't address that any more. So that only leaves option #2.
You could use NAnt to build your individual CSproj projects and use your NAnt build script to define the dependencies between projects. There are two downsides to this.
On downside #2, Visual Studio wouldn't be able to compile your solution as a whole because that logic would have been shifted out of VS and into an external build script. This could lead to confusion among developers, and would hinder the debugging process. Not saying those things aren't overcome-able... just saying that it would be extra setup involved at those steps of the development process.