88

We have a solution with around 100+ projects, most of them C#. Naturally, it takes a long time to both open and build, so I am looking for best practices for such beasts. Along the lines of questions I am hoping to get answers to, are:

  • how do you best handle references between projects
    • should "copy local" be on or off?
  • should every project build to its own folder, or should they all build to the same output folder(they are all part of the same application)

  • Are solutions' folders a good way of organizing stuff?

I know that splitting the solution up into multiple smaller solutions is an option, but that comes with its own set of refactoring and building headaches, so perhaps we can save that for a separate thread :-)

4

12 回答 12

42

You might be interested in these two MSBuild articles that I have written.

MSBuild: Best Practices For Creating Reliable Builds, Part 1

MSBuild: Best Practices For Creating Reliable Builds, Part 2

Specificially in Part 2 there is a section Building large source trees that you might want to take a look at.

To briefly answer your questions here though:

  • CopyLocal? For sure turn this off
  • Build to one or many output folders? Build to one output folder
  • Solution folders? This is a matter of taste.

Sayed Ibrahim Hashimi

My Book: Inside the Microsoft Build Engine : Using MSBuild and Team Foundation Build

于 2009-06-22T21:59:20.257 回答
9

+1 for sparing use of solution folders to help organise stuff.

+1 for project building to its own folder. We initially tried a common output folder and this can lead to subtle and painful to find out-of-date references.

FWIW, we use project references for solutions, and although nuget is probably a better choice these days, have found svn:externals to work well for both 3rd party and (framework type) in-house assemblies. Just get into the habit of using a specific revision number instead of HEAD when referencing svn:externals (guilty as charged:)

于 2009-03-27T14:51:08.063 回答
8

卸载您不经常使用的项目,并购买 SSD。SSD 不会缩短编译时间,但 Visual Studio 的打开/关闭/构建速度会提高两倍。

于 2009-06-24T15:27:53.393 回答
6

我们有一个类似的问题,因为我们有 109 个单独的项目要处理。根据我们的经验回答最初的问题:

1. 你如何最好地处理项目之间的引用

我们使用“添加参考”上下文菜单选项。如果选择了“项目”,则默认情况下会将依赖项添加到我们的单个全局解决方案文件中。

2.“复制本地”应该打开还是关闭?

根据我们的经验。额外的复制只会增加构建时间。

3.每个项目应该构建到自己的文件夹,还是应该都构建到同一个输出文件夹(它们都是同一个应用程序的一部分)

我们所有的输出都放在一个名为“bin”的文件夹中。想法是该文件夹与部署软件时相同。这有助于防止在开发人员设置与部署设置不同时发生的问题。

4.解决方案文件夹是组织东西的好方法吗?

在我们的经验中没有。一个人的文件夹结构是另一个人的噩梦。深度嵌套的文件夹只会增加查找任何内容所需的时间。我们有一个完全扁平的结构,但我们的项目文件、程序集和命名空间的名称相同。


我们构建项目的方式依赖于单个解决方案文件。构建这个需要很长时间,即使项目本身没有改变。为了解决这个问题,我们通常会创建另一个“当前工作集”解决方案文件。我们正在进行的任何项目都会被添加到其中。构建时间大大缩短,尽管我们看到的一个问题是 Intellisense 对不在当前集合中的项目中定义的类型失败。

我们的解决方案布局的部分示例:

\bin

OurStuff.SLN

OurStuff.App.Administrator
OurStuff.App.Common
OurStuff.App.Installer.Database
OurStuff.App.MediaPlayer
OurStuff.App.Operator
OurStuff.App.Service.Gateway
OurStuff.App.Service.CollectionStation
OurStuff.App.ServiceLocalLauncher
OurStuff.App.StackTester
OurStuff.Auditing
OurStuff.Data
OurStuff.Database
OurStuff.Database.Constants
OurStuff.Database.ObjectModel
OurStuff.Device
OurStuff.Device.Messaging
OurStuff.Diagnostics
...
[etc]
于 2009-05-03T09:08:14.223 回答
4

We work on a similar large project here. Solution folders has proved to be a good way of organising things, and we tend to just leave copy local set to true. Each project builds to its own folder, and then we know for each deployable project in there we have the correct subset of the binaries in place.

As for the time opening and time building, that's going to be hard to fix without breaking into smaller solutions. You could investigate parallelising the build (google "Parallel MS Build" for a way of doing this and integrating into the UI) to improve speed here. Also, look at the design and see if refactoring some of your projects to result in fewer overall might help.

于 2009-03-27T14:49:22.343 回答
3

In terms of easing the building pain, you can use the "Configuration Manager..." option for builds to enable or disable building of specific projects. You can have a "Project [n] Build" that could exclude certain projects and use that when you're targeting specific projects.

As far as the 100+ projects goes, I know you don't want to get hammered in this question about the benefits of cutting down your solution size, but I think you have no other option when it comes to speeding up load time (and memory usage) of devenv.

于 2009-03-27T14:49:58.393 回答
3

What I typically do with this depends a bit on how the "debug" process actually happens. Typically though I do NOT set copy local to be true. I setup the build directory for each project to output everything to the desired end point.

Therefore after each build I have a populated folder with all dll's and any windows/web application and all items are in the proper location. Copy local wasn't needed since the dll's end up in the right place in the end.

Note

The above works for my solutions, which typically are web applications and I have not experienced any issues with references, but it might be possible!

于 2009-03-27T14:51:51.323 回答
3

我们有一个类似的问题。我们使用较小的解决方案来解决它。我们有一个可以打开一切的主解决方案。但性能。那是不好的。因此,我们按开发人员类型细分较小的解决方案。所以,DB 开发人员有一个解决方案,可以加载他们关心的项目,服务开发人员和 UI 开发人员是一样的。很少有人不得不打开整个解决方案来完成他们每天需要做的事情。它不是灵丹妙药——它有它的优点和缺点。请参阅本文中的“多解决方案模型” (忽略有关使用 VSS 的部分:)

于 2009-05-03T03:00:41.783 回答
2

我们有大约 60 多个项目,我们不使用解决方案文件。我们混合了 C# 和 VB.Net 项目。性能一直是个问题。我们不会同时处理所有项目。每个开发人员都会根据他们正在处理的项目创建自己的解决方案文件。解决方案文件不会检查到我们的源代码管理中。

所有类库项目都将构建到源目录根目录下的 CommonBin 文件夹中。可执行文件/Web 项目构建到它们各自的文件夹中。

我们不使用项目引用,而是使用 CommonBin 文件夹中基于文件的引用。我编写了一个自定义 MSBuild 任务,它将检查项目并确定构建顺序。

我们已经使用它几年了,没有任何抱怨。

于 2009-06-05T17:52:42.443 回答
2

我认为对于这么大的解决方案,最佳实践应该是将它们分解。您可以将“解决方案”视为汇集必要项目的地方,也许还有其他部分来解决问题。通过将 100 多个项目分解为多个解决方案,专门针对整体问题的一部分开发解决方案,通过加快与所需项目的交互并简化问题域,您可以在特定时间处理更少的问题。

每个解决方案都会产生它负责的输出。此输出应具有可以在自动化过程中设置的版本信息。当输出稳定时,您可以使用最新的内部分发更新依赖项目和解决方案中的引用。如果您仍然想单步执行代码并访问源代码,您实际上可以使用 Microsoft 符号服务器来执行此操作,Visual Studio 可以使用它来允许您单步执行引用的程序集,甚至获取源代码。

可以通过预先指定接口并模拟正在开发的程序集来完成同时开发,同时您正在等待不完整但您希望开发的依赖项。

我发现这是一种最佳实践,因为当您以这种方式进行物理分解时,整体工作的复杂程度是没有限制的。将所有项目放在一个解决方案中最终会达到上限。

希望这些信息有所帮助。

于 2009-05-06T02:58:25.697 回答
0

设置 CopyLocal=false 将减少构建时间,但在部署期间可能会导致不同的问题。

在很多情况下,您需要将 Copy Local' 保留为 True,例如顶级项目、二级依赖项、反射调用的 DLL。

我设置 CopyLocal=false 的经验并不成功。请参阅我的博客文章“请勿将“复制本地”项目引用更改为 false中的优缺点摘要,除非了解子序列。

于 2012-12-09T02:36:58.763 回答
0

这一切都与您对解决方案和项目的定义和看法有关。在我看来,解决方案就是这样,一个解决非常特定需求的项目的逻辑分组。我们开发了一个大型的 Intranet 应用程序。该 Intranet 中的每个应用程序都有自己的解决方案,其中还可能包含用于 exe 或 Windows 服务的项目。然后我们有一个集中的框架,其中包含基类和助手以及 httphandlers/httpmodules 之类的东西。基础框架相当大,被所有应用程序使用。通过以这种方式拆分多个解决方案,您可以减少解决方案所需的项目数量,因为它们中的大多数彼此无关。

在一个解决方案中拥有这么多项目只是糟糕的设计。没有理由在一个解决方案下拥有这么多项目。我看到的另一个问题是项目引用,它们最终真的会把你搞砸,特别是如果你想把你的解决方案分成更小的解决方案。

我的建议是这样做并开发一个集中式框架(如果您愿意,您可以自己实现企业库)。您可以 GAC 共享它,也可以直接引用文件位置,以便拥有中央存储。您也可以对集中式业务对象使用相同的策略。

如果您想直接引用 DLL,您需要在项目中使用 copy local false 来引用它(例如 c:\mycompany\bin\mycompany.dll)。运行时,您需要向 app.config 或 web.config 添加一些设置,以使其引用不在 GAC 或运行时 bin 中的文件。实际上,无论它是否是本地复制,或者 dll 是否最终在 bin 中或什至在 GAC 中,都无关紧要,因为配置将覆盖这两者。我认为复制本地并且系统混乱是不好的做法。如果您需要调试到其中一个程序集,您很可能必须临时复制本地。

您可以阅读我关于如何在没有 GAC 的情况下全局使用 DLL 的文章。我真的不喜欢 GAC,主要是因为它阻止了 xcopy 部署并且不会触发应用程序的自动重启。

http://nbaked.wordpress.com/2010/03/28/gac-alternative/

于 2010-04-02T05:16:26.517 回答