visual-studio 如何拆分 Visual Studio 解决方案?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2037985/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 11:22:53  来源:igfitidea点击:

How do you split a Visual Studio Solution?

visual-studiovisual-studio-2008

提问by Niki

I have a Visual Studio 2008 solution with >40 C# and C++/CLI projects that depend on each other. Working with that solution is quite slow, and usually I only need a few projects at a time. So I decided to split the solution into multiple solutions that contain 3-5 projects. I would also like to keep the "full" solution with all projects (it's handy for for automated builds or for big refactoring actions that affect all projects).(This is the main condition here. Otherwise, splitting projects into solutions is trivial, of course.)

我有一个 Visual Studio 2008 解决方案,其中包含超过 40 个相互依赖的 C# 和 C++/CLI 项目。使用该解决方案非常缓慢,通常我一次只需要几个项目。所以我决定将解决方案拆分为包含 3-5 个项目的多个解决方案。我还想保留所有项目的“完整”解决方案(这对于自动构建或影响所有项目的大型重构操作非常方便)。(这是这里的主要条件。否则,当然,将项目拆分为解决方案是微不足道的。)

Is there any way to do that?

有没有办法做到这一点?

My first idea was to create new empty solutions and add some of the existing project files into each of these solutions. But if I do that, VS can't find the project references any more (because they're not in the same solution). I can add the references as "normal" file references. But if I do that, my "full" solution doesn't work any more, because the dependencies are lost.

我的第一个想法是创建新的空解决方案并将一些现有的项目文件添加到每个解决方案中。但是如果我这样做,VS 就再也找不到项目引用了(因为它们不在同一个解决方案中)。我可以将引用添加为“普通”文件引用。但是如果我这样做,我的“完整”解决方案将不再起作用,因为依赖关系丢失了。

EDIT:

编辑:

Thank you all for your answers. I'd like to clarify my question a bit: My solution contains 44 projects, not including tests. So splitting it into 2 parts isn't really what I had in mind, I was more thinking about 5-8 parts. That's why I would like to keep the "full" solution where VS can figure out the correct build order for a full build. Maintaining the build order for 8 separate solutions by hand (e.g. in a batch file) seems error-prone to me.

谢谢大家的答案。我想澄清一下我的问题:我的解决方案包含 44 个项目,不包括测试。所以将它分成 2 部分并不是我真正的想法,我更多地考虑了 5-8 部分。这就是为什么我想保留“完整”解决方案,其中 VS 可以找出完整构建的正确构建顺序。手动维护 8 个单独解决方案的构建顺序(例如在批处理文件中)对我来说似乎容易出错。

Also I would like to group the projects "logically" (i.e. I would like to have the projects that are usually modified together in one solution). But that grouping does not always match the dependencies. For example, imagine I have the dependency chain

此外,我想“按逻辑”对项目进行分组(即,我希望将通常在一个解决方案中一起修改的项目)。但该分组并不总是与依赖项匹配。例如,假设我有依赖链

A is referenced by B is referenced by C is referenced by D

and imagine that A and D are often modified together but B and C rarely change. (Obviously, the interface of A that is used by B must remain unchanged for that.) Then I would like to have A and D in one solution, B and C in another. But that would only work if I could have an intact "complete" solution containing A,B,C and D if I want to build all projects from scratch. Once that build is complete, I could open my A/D-solution and edit/build only those 2 projects.

并想象 A 和 D 经常一起修改,但 B 和 C 很少改变。(显然,B 使用的 A 的接口必须为此保持不变。)然后我希望 A 和 D 在一个解决方案中,B 和 C 在另一个解决方案中。但是,如果我想从头开始构建所有项目,那么只有当我可以拥有包含 A、B、C 和 D 的完整“完整”解决方案时,这才有效。构建完成后,我可以打开我的 A/D 解决方案并仅编辑/构建这 2 个项目。

But I fear there is no elegant solution for my problem. (pun not intended)

但我担心我的问题没有优雅的解决方案。(双关语不是故意的)

采纳答案by Russell Mull

There's no good way to do this. The tools aren't built with that in mind. Instead, you should combine your projects together as much as you can. Even though it's the same amount of code, builds will run many times faster.

没有好的方法可以做到这一点。这些工具并没有考虑到这一点。相反,您应该尽可能多地将您的项目组合在一起。即使代码量相同,构建的运行速度也会快很多倍。

You'll have to get over the idea that separate projects are required for having good abstractions. It seems like a very clean way to enforce separation. But it's not worth the price with this toolchain. Use the language features instead; classes, namespaces, and so on.

您必须克服这样的想法,即拥有良好的抽象需要单独的项目。这似乎是强制分离的一种非常干净的方式。但是这个工具链不值这个价。改用语言特性;类、命名空间等。

回答by Nick Craver

Another approach you may want to consider is to just unload the projects you are not using, just right click and unload the ones you're not working on...this should result in a much snappier Visual Studio. It keeps a lot of stuff out of VS memory.

您可能要考虑的另一种方法是卸载您不使用的项目,只需右键单击并卸载您不使用的项目......这应该会导致 Visual Studio 更加快速。它使很多东西脱离了 VS 内存。

Something else you can do is edit the build definition and remove any unmodified projects (depending on how you links are...you know what's needed/updated/not needed).

您可以做的其他事情是编辑构建定义并删除任何未修改的项目(取决于您的链接方式……您知道需要/更新/不需要什么)。

Solution-> Right Click -> Configuration Manager-> uncheck Buildon any projects that don't change and aren't needed every buildfor some other reason. This speeds up your build by using the output of the last build of these projects, from wherever they dump their binaries to.

解决方案-> 右键单击​​ ->配置管理器->在任何未更改且由于其他原因不需要每次构建的项目上取消选中构建。这通过使用这些项目的最后一次构建的输出来加速您的构建,无论它们将二进制文件转储到何处。

Note:You can still right click a project and build to update it's output then rebuild the solution to get the latest...you can do this instead of changing the build configuration back and forth to include it.

注意:您仍然可以右键单击一个项目并构建以更新它的输出,然后重建解决方案以获取最新版本...您可以这样做而不是来回更改构建配置以包含它。

Update
In the spirit of going the performance route (e.g. waiting until VS 2010 really), have you taken the measures listed in some other stack overflow questions: Very slow compile times on Visual Studioand Visual Studio Optimizations? These can make quite a difference, and may bring performance to an acceptable level while we wait on VS 2010 to ship.
A few more things that can have a good impact on performance:

更新
本着走性能路线的精神(例如真正等到 VS 2010),您是否采取了其他一些堆栈溢出问题中列出的措施:Visual StudioVisual Studio 优化的编译时间很慢?这些可以产生很大的不同,并且可以在我们等待 VS 2010 发布时将性能提高到可接受的水平。
还有一些可以对性能产生良好影响的事情:

  • I highly recommend an SSDif it's an option. They are costly but definitely worth it, the more files in your solution they more they pay off. When we ordered new machines at work the entire development team went with SSDs, the difference is astounding. When you're dealing with a large solution, it's spinning the drive around switching the physical head to thousands of locations just to read the files in...that's where SSDs win, seek time is effectively 0ms.
  • Along the same lines, a free solution is a good drafragmenter (only if you're on a physical, do NOT defrag a SSD) makes a big difference...if you use something that's keeping visual studio in mind. I recommend MyDefrag(freeware) as it's native algorithm for defragging keeps directory structure in mind, so at least a physical drive doesn't spend as much time switching around to steam the files you need in your solution, they're all very close on the disk.
  • With the above SSD suggestion, keep in mind there is a huge disparity in SSD performance between a cheap and a fast drive, do a little bit of research here. Don't worry about your system, with a free utility such as gPartedyou can move your entire OS drive over very easily, and your old drive will still be a backup...as long as the SSD can fit the data off your C, you're good.
  • 如果可以的话,我强烈推荐 SSD。它们很昂贵,但绝对值得,您的解决方案中的文件越多,它们的回报就越大。当我们在工作中订购新机器时,整个开发团队都使用 SSD,差异令人震惊。当您处理大型解决方案时,它会旋转驱动器,将物理磁头切换到数千个位置,只是为了读取文件……这就是 SSD 获胜的地方,寻道时间实际上是 0 毫秒。
  • 同样,一个免费的解决方案是一个很好的 drafragmenter(只有当你在物理上,不要对 SSD进行碎片整理)会产生很大的不同......如果你使用的是记住视觉工作室的东西。我推荐MyDefrag(免费软件),因为它是用于碎片整理的本地算法,记住目录结构,所以至少物理驱动器不会花太多时间来切换解决方案中需要的文件,它们都非常接近磁盘。
  • 有了上述 SSD 建议,请记住,廉价和快速驱动器之间的 SSD 性能存在巨大差异,请在此处进行一些研究。不用担心您的系统,使用gParted 等免费实用程序您可以非常轻松地移动整个操作系统驱动器,并且您的旧驱动器仍将是备份...只要 SSD 可以容纳您的 C 上的数据, 你很厉害。

回答by Jason Williams

You can make multiple solutions and add any project(s) to each solution that you like.

您可以制作多个解决方案并将任何项目添加到您喜欢的每个解决方案中。

The projects you wish to build may have dependencies on other projects. In this case, you need to change from using a "Project" reference (whch references any other project in the solution) to using a File reference (where you reference the assembly .dll that project has created).

您希望构建的项目可能依赖于其他项目。在这种情况下,您需要从使用“项目”引用(引用解决方案中的任何其他项目)更改为使用文件引用(在其中引用项目已创建的程序集 .dll)。

So let's think of them as "libraries" (compiled once and then used a lot), and "core" projects (that you are changing a lot). Make solution(s) to contain your "library" projects, and (preferably) add a post-build step that copies the resulting debug/release dlls into shared library folders. Add the core projects to a new solution. Change all the core solution references to refer to your libraries via the pre-built binary dlls in your shared folders (refer to the release build dll, so that your final release works properly).

因此,让我们将它们视为“库”(编译一次然后使用很多)和“核心”项目(您正在更改很多)。制作解决方案以包含您的“库”项目,并(最好)添加一个构建后步骤,将生成的调试/发布 dll 复制到共享库文件夹中。将核心项目添加到新解决方案中。将所有核心解决方案引用更改为通过共享文件夹中的预构建二进制 dll 引用您的库(请参阅发布构建 dll,以便您的最终版本正常工作)。

If you change a library then you need to build the library solution to rebuild it, and then use the core solution to rebuild the application(s) that depend on the library. (Thus it is a good idea to put any frequently-changed code in the core solution rather than in a library. You can move projects about at a later date when they mature, and/or make libraires into core projects if they need to be heavily modified for a while)

如果更改库,则需要构建库解决方案来重建它,然后使用核心解决方案重建依赖于该库的应用程序。(因此,将任何经常更改的代码放在核心解决方案中而不是放在库中是个好主意。您可以在项目成熟时稍后移动项目,和/或在需要时将库放入核心项目中大量修改了一段时间)

[2018 edit] These days, libraries can be distributed using local nuget or npm servers, which would be a preferred option unless there is a specific reason not to adopt this approach.

[2018 编辑] 如今,可以使用本地 nuget 或 npm 服务器分发库,除非有特定原因不采用这种方法,否则这将是首选选项。

A last option, in cases of libraries that take a while to build and which change very infrequently, is to make them "precompiled" libraries - check the final dll files in to source control, and your team members can just get the latest version and build against the libraries without needing to get or build the source code for them at all. (To update these libraries you must remember to check out the binary .dll files before building and then check them in again after rebuilding them, so you have to weigh the advantages (faster & easier day-to-day builds) against the disadvantages (a bit more effort to make changes to the libraries, larger binary files in source control).

最后一个选择,对于需要一段时间构建并且很少更改的库,是使它们“预编译”的库 - 将最终的 dll 文件检查到源代码管理中,您的团队成员可以获得最新版本和针对库进行构建,根本不需要获取或构建它们的源代码。(要更新这些库,您必须记住在构建之前检出二进制 .dll 文件,然后在重建它们之后再次检入它们,因此您必须权衡优点(更快和更容易的日常构建)与缺点(更努力地对库进行更改,在源代码管理中使用更大的二进制文件)。

回答by sinelaw

Three years after your question, ourteam is still facing the same problem - not compile time, but the fact that there is no good way to split what is logically separate into separate solutions.

在您提出问题三年后,我们的团队仍然面临同样的问题——不是编译时间,而是没有好的方法将逻辑上分离的内容拆分为单独的解决方案。

We ended up building our own toolin the form of soldr (open source), an inter-solution build tool. It can optionally leverage nugetto manage your code base or work on its own. The idea is to split your work into as many solutions (.sln's) as makes sense logically. In our case we have one for our in-house framework, and then one slnfor each our back end libraries, one for each product, etc. Each solution has a "components" directory (similar to nuget "packages" dir) where we store the actual library files (DLLs, etc.) which are being referenced by the current solution. These DLLs have to be updated from a fresh build of the dependency for the target sln to see a new version.

我们最终以soldr(开源)的形式构建了我们自己的工具,这是一种解决方案间构建工具。它可以选择利用nuget来管理您的代码库或独立工作。这个想法是将您的工作拆分为符合逻辑的尽可能多的解决方案(.sln)。在我们的例子中,我们有一个用于我们的内部框架,然后一个用于我们的后端库,一个用于每个产品,等等。每个解决方案都有一个“组件”目录(类似于 nuget“包”目录)我们存储当前解决方案引用的实际库文件(DLL 等)。这些 DLL 必须从目标 sln 的依赖项的新版本进行更新才能看到新版本。sln

Instead of manual labor we then use our aforementioned build tool. Using very simple rules and conventions it automatically infers the inter-solution dependencies. It can then build the entire dependency graph correctly (or generate an MSBuild file to do so), at each step building and copying the outputs to the components directory of the next target. We also added features for filtering what will be built (e.g. build only the direct dependencies), printing dependency graphs, running unit tests, etc.

然后我们使用前面提到的构建工具代替手工劳动。使用非常简单的规则和约定,它会自动推断解决方案间的依赖关系。然后它可以正确构建整个依赖关系图(或生成一个 MSBuild 文件来执行此操作),在每个步骤构建并将输出复制到下一个目标的组件目录。我们还添加了用于过滤将要构建的内容(例如仅构建直接依赖项)、打印依赖项图、运行单元测试等的功能。

Update: To leverage nugetwe've added support for generating nuspecfiles with automatically inferred dependencies.

更新:为了利用nuget,我们添加了对生成nuspec具有自动推断依赖项的文件的支持。

回答by Grant

We have 500+ projects in a solution. There are benefits to keeping every project in a single solution, especially when a base project is changed that effects all other projects (e.g., helper classes).

我们在一个解决方案中有 500 多个项目。将每个项目保留在单个解决方案中是有好处的,尤其是当基础项目发生更改会影响所有其他项目(例如,帮助程序类)时。

We found the best way to continue was to use the vsFunnel extensionfor Visual Studio. It has the ability to load a solution WITHOUT the projects. The projects are still listed in the solution but not actually loaded until needed. As a project is opened via the UI it is loaded on demand.

我们发现最好的方法是使用Visual Studio的vsFunnel 扩展。它能够在没有项目的情况下加载解决方案。这些项目仍列在解决方案中,但在需要时才实际加载。当项目通过 UI 打开时,它会按需加载。

The real trick is to enable "Load Dependencies" from the vsFunnel UI. As you open a project, it loads all the dependent projects, etc. which makes working on a target project much easier.

真正的技巧是从 vsFunnel UI 启用“加载依赖项”。当您打开一个项目时,它会加载所有相关项目等,这使得处理目标项目变得更加容易。

For example, in our 500+ projects, often we are focused on a single application, and it might have 20 dependent projects. Only those are loaded, NOT the entire 500+.

例如,在我们的 500 多个项目中,通常我们专注于单个应用程序,它可能有 20 个依赖项目。只有那些被加载,而不是整个 500+。

Hint: Choose Load Dependencies AND Load None - then when you open your target project in the UI, all related projects are loaded.

提示:选择 Load Dependencies 和 Load None - 然后当你在 UI 中打开你的目标项目时,所有相关的项目都会被加载。

This has turned out to be an enormous time saver (plus an SSD drive!)

事实证明,这节省了大量时间(加上 SSD 驱动器!)

回答by Jason Williams

Another option is to have a single all-encompassing solution, and create different build configurations.

另一种选择是拥有一个包罗万象的解决方案,并创建不同的构建配置。

At the top of the window is a combobox where you can choose Debug or Release build configuration. Drop this down and choose the "Configuration Manager..." option.

窗口顶部是一个组合框,您可以在其中选择调试或发布构建配置。将其下拉并选择“配置管理器...”选项。

Under "Active Solution Configuration", drop down the combo box and choose <New...>. Create a new configuration (for example, called "CoreOnly") and select "Copy settings from" as "Debug". Untickthe "Create new project configurations" option.

在“Active Solution Configuration”下,下拉组合框并选择<New...>。创建一个新配置(例如,称为“CoreOnly”)并选择“Copy settings from”作为“Debug”。取消勾选“创建新项目配置”选项。

Now, your "CoreOnly" build configuration will appear in the window. It shows a list of all the projects. For any projects that you don't want to build, untick the "Build" checkbox in the right hand column. Close the dialog.

现在,您的“CoreOnly”构建配置将出现在窗口中。它显示了所有项目的列表。对于您不想构建的任何项目,请取消选中右侧栏中的“构建”复选框。关闭对话框。

Now, to build all the projects, choose "Debug" from the configuration dropdown, and Build as normal. When all your projects have built, you can drop down to only building the "core" projects by switching to the CoreOnly configuration. As long as you remember to build the Debug (all projects) build when you edit code that is not in any of the core projects, you'll be fine, and your CoreOnly builds will be much faster.

现在,要构建所有项目,请从配置下拉列表中选择“调试”,然后正常构建。当您的所有项目都构建完毕后,您可以通过切换到 CoreOnly 配置来下拉以仅构建“核心”项目。只要您在编辑不在任何核心项目中的代码时记得构建 Debug(所有项目)构建,您就会没事,并且您的 CoreOnly 构建会快得多。

The down sidesof this approach are that the solution can be very slow to open (although in Visual Studio 2008, Visual Studio 2010and Visual Studio 2012this is a lot better than it was in Visual Studio 2005, so you may not have a problem with it) and that if a project isn't enabled in your configuration, it won't ever be rebuiltand so your build (or the running application) can fall apart - you have to remember to switch back to the regular "build everything" configuration if you think you have made changes in (or affecting) the disabled projects.

降双方这种方法的是,该解决方案可以非常慢开(尽管在Visual Studio 2008中视觉2010工作室的Visual Studio 2012,这是好了很多,比它在Visual Studio 2005中,所以你可能不会有问题使用它)并且如果您的配置中未启用一个项目,它将永远不会被重建,因此您的构建(或正在运行的应用程序)可能会崩溃 - 您必须记住切换回常规的“构建所有内容” " 配置,如果您认为您已对(或影响)禁用的项目进行了更改。

回答by Brian T Hannan

You should have separation of concerns, especially when grouping projects within a Visual Studio Solution. I recently ran into this problem at work where I had to create a bunch of unit tests and the original test created by the developer was included in the solution. At first, I thought O.K. I'll just put my tests in here b/c I know it will work and don't have to worry about getting the dependencies right. But then later on after I added like 20 test projects for each different unit I realized it was building so incredibly slow.

您应该分离关注点,尤其是在 Visual Studio 解决方案中对项目进行分组时。我最近在工作中遇到了这个问题,我不得不创建一堆单元测试,而开发人员创建的原始测试包含在解决方案中。起初,我想好,我会把我的测试放在这里 b/c 我知道它会工作并且不必担心获得正确的依赖关系。但是后来我为每个不同的单元添加了大约 20 个测试项目后,我意识到它的构建速度非常慢。

I then decided to create a solution for EACH set of tests rather than putting them all in one spot. This also helps organize your code better so it's easier to find. For example, I created a folder 'Test > Unit > MyUnitTest' and 'Test > Integration > MyIntegrationTest.' Not only does it make it easy to find things later on, but it helps you make your builds faster. Also, if there a bunch of people working on the code at once each developer could potentially change the project settings and configurations and not mess up the others.

然后我决定为每组测试创建一个解决方案,而不是将它们全部放在一个地方。这也有助于更好地组织您的代码,以便更容易找到。例如,我创建了一个文件夹“Test > Unit > MyUnitTest”和“Test > Integration > MyIntegrationTest”。它不仅可以让您以后轻松查找内容,还可以帮助您加快构建速度。此外,如果有一群人同时处理代码,每个开发人员都可能会更改项目设置和配置,而不会弄乱其他人。

The general rule is to have only 7 items or less grouped together in one certain area. If you have more than 7 items then chances are there is another sub-category you could create to make it more abstract and easier for the human brain to comprehend all the complicated details at a glance (especially for people new to the system or if you are coming back to the project months or even years later).

一般规则是在一个特定区域内只将 7 个或更少的项目组合在一起。如果您有 7 个以上的项目,那么您很可能可以创建另一个子类别,使人脑更抽象,更容易一目了然地理解所有复杂的细节(尤其是对于系统的新手,或者如果您几个月甚至几年后回到项目中)。

回答by watbywbarif

Besides here mentioned soldrand FunnelI can recomend using Solution Load Manager. Yea, SSD helps, but VS is buggy: it crashes, becomes unresponsive and other problems emerge when working on 100+ projects. Keeping it all together for major refactoring, rebuilding and debugging is a must have, but working on smaller subsets of projects on daily bases will greatly improve performance and satisfaction.

除了这里提到的焊料漏斗,我可以推荐使用 解决方案负载管理器。是的,SSD 有帮助,但 VS 有问题:在处理 100 多个项目时,它会崩溃、变得无响应并出现其他问题。必须将它们放在一起进行主要重构、重建和调试,但每天处理较小的项目子集将大大提高性能和满意度。

ps. I would like to know if someone has made comparison Funnel vs. Solution Load Manger?

附:我想知道是否有人比较过漏斗与解决方案负载管理器?