Visual Studio解决方案:这些解决方案有太多项目吗?

时间:2011-07-06 20:40:34

标签: .net visual-studio projects-and-solutions

在我目前工作的公司中,我们支持4个有些相关的Windows应用程序。对于每个应用程序,我们都有一个解决方案,每个解决方案从50到100个项一个或多个解决方案之间可能共有40或50个项目。

为了给你一个想法,更大的解决方案有近90个项目,其中20个是UI项目(主要应用程序,自定义控件项目,UI助手项目),另外20个是Business Layer项目,可能有30或40个数据访问层项目,其余是Windows服务项目和专门项目

我一直觉得每个解决方案中都有太多项目。当然,我们正在谈论大型应用程序,但我不明白为什么许多项目无法合并。在我以前的公司中,我们实际上有一个用于业务层的项目,一个用于DAL的项目,显然每个窗口或Web应用程序都有一个项目。

以下是由于项目数量众多而遇到的一些问题:

  • 编译时间很长。
  • 通常应该是私有的类需要公开才能被同一层中的其他项目访问。
  • 我最近开始使用Profileer Eqateq。试用版允许分析最多10个dll。我的情况显然使用此应用程序变得复杂。
  • 跟踪项目之间的引用非常复杂。我确信项目之间有很多未使用的引用。

相比之下,我没有发现这种情况的优势。

所以,我的问题是:

  • 您何时决定创建一个新项目,而不仅仅是在当前项目中创建一个文件夹?
  • 我有什么优势可以忽略吗?

更新

请记住,我并不是建议为所有事情设计一个项目。至少应该有一个DAL项目,一个用于BL,一个用于每个UI应用程序。我意识到即使这对大多数应用来说也是不现实的。 我想要了解的是,为组装定义“单一责任”级别的最佳实践是什么?我的意思是,这是一个非常主观的问题,如果采取极端措施,将导致每个班级有一个集会。

更新2:

所有三个答案都提供了有价值的信息,但我只能选择一个我选择Doc的评论如何确定DAL项目的数量。 我还链接到我刚发现的其他问题,这些问题包含相关信息:Herehere。 我还建议您阅读this article

5 个答案:

答案 0 :(得分:9)

我们主要讨论.NET项目,对吧?将应用程序拆分为不同的项目/程序集会强制您避免这些项目之间的循环依赖关系,因为C#和VB.NET编译器会禁止这样做。如果您将所有内容放入一个大项目中,则每个类都可以引用该项目中的每个其他类,从而允许您创建真正的依赖性噩梦。如果您要在团队中使用单元测试和开发,那么如果团队成员可以在不同的,隔离的DLL上工作并单独测试它们,那么这将更加容易。

“跟踪引用”是你问题的一部分:如果你把所有东西放到一个大的DLL中,你的类之间就有相同的引用,就好像你有单独的DLL一样,但你不能再控制它们了。同样适用于“私人”课程(你的意思是“内部”,我认为?)

当然,我不能告诉你的是,如果你的90个项目是精心挑选的工作单元。这是一个“单一责任”的问题,正确的抽象级别和由此产生的依赖关系,只有知道您的应用程序系统的人才能回答。

编辑:到目前为止,我已经阅读了一些关于通过命名空间定义组件边界,并将几个组件放入一个物理组件/一个VS项目来降低编译时间的文章(like this one)。为了使这种方法可行,可能需要像NDepend或类似的工具来确保组件之间没有循环依赖关系。对于大型项目,这可能是更好的选择。

答案 1 :(得分:1)

有很多项目并不一定是坏事。

它的一大优势是拥有模块来创建带有图层的架构。也就是说,你Gui类可以引用较低层,但不能相反。

如果您有一个较低层(例如,业务逻辑)引用上层(gui),您将具有循环依赖,并且visual studio将拒绝构建您的解决方案。

如果您将所有项目混合到一个项目中,则不会发生这种情况。当然,如果你在代码上运行DSM software,你可以发现这一点,但是让你的编译器帮助你更安全。

关于让您可以私下上课的观点让我更多地考虑您的 API 。这些项目不应该合并在一起,或者不应该合并这些类 被提取到第三个项目。在思考这些问题时,我试着在层层思考,没有银弹。

对于属于项目 ONLY 的类,我通常会在这些必须声明为public的“内部”类的名称空间中添加“内部”(或“详细”)字。例如:您将知道 MyApplication.Model.Publisher 中的任何类都不应访问以下任何类: MyApplication.Model.Vendors.Internal 。这是我在Eclipse API上看到的一种技术。

我知道C#有内部关键字,但有时候人们会在没有考虑的情况下将其声明为公开。将它放在名称上是一种更强大的方法,因为要使该类公开需要更多的工作。

使用真正庞大的软件的其他方法是插件方式,因此它将使您的构建时间更短。它总是带着你的价格。您可以查看OSGI

答案 2 :(得分:1)

如果给定解决方案中的项目数量导致每日烦恼(例如,由于解决方案加载和编译时间),那么您确实在解决方案中有太多项目。也就是说,替代方案也有点烦人,所以你必须找出你的“快乐媒介”所在。

为至少一部分项目引用预编译程序集而不是解决方案项目是一种可以减少项目数量而不影响任何有关功能隔离的预先存在的决策的方法。它还可以带来其他好处,特别是在大型团队中。例如,在更严格的测试之后,引用的程序集可以发布给团队的其他成员,而不是简单地每当在其中一个引用的项目上工作的开发人员检查到源代码控制的更改时。

虽然循环依赖避免绝对是可取的,但我已经看到装配隔离被带到一些相当荒谬的极端。有一些工具(例如:NDepend,FxCop)可以帮助检测不适当的依赖关系,而且当不适当的依赖性避免是隔离的唯一原因时,我倾向于倾向于使用它们而不是程序集隔离。

答案 3 :(得分:1)

看起来这是预成熟优化的典型例子。您的团队中的开发人员似乎正在创建许多项目,可能是由于历史性的架构原因,并且您通过质疑这种方法做了正确的事情。

我个人的观点是从每层一个项目开始(如你所述),例如一个用于GUI,一个用于业务层,一个用于DAL等。解决方案的其他项目只应在特定需求出现时创建而不是过早。此时,您可以重构您的解决方案,将项目“文件夹”移动到其自己的单独项目中。

这将确保: - 构建时间更快 - 您拥有项目所需的确切项目数量 - 您已经记录了为什么要创建特定项目(需要它实现的目标)的推理

在解决方案中创建许多特定项目只是“过度工程”。您不会过度设计代码并在不需要的位置创建类。您需要重构代码,以便在需要时包含一个单一职责的类。这同样适用于解决方案和项目。

答案 4 :(得分:0)

我认为这里的真正问题是单一责任之一。我并不是说在类设计方面,我是指.Net项目的目的。

通常一个项目用于:
1.构建一些代码以输出DLL,EXE,网站,API等。
2.控制对解决方案中代码的访问和构建

根据我的经验,大多数项目用于2。 这在大型解决方案中导致的是非常广度优先的结构,该结构会很快变得不直观,构建速度变慢,Visual Studio速度变慢(您好!),这意味着大量的依赖项从一个容器移到另一个容器,这使得您不需要的所有这些DLL其实并不需要。

例如,如果c#访问修饰符可以在名称空间边界(而不是Project)处表示,那么我们就不需要这样做,并且可以具有有意义的直观名称空间层次结构,在该层次结构中,如果实际需要生成,则只需要一个项目DLL。当然,我还没有完全考虑到这一点,但是在解决方案中有这么多项目,我觉得有些不对。

Java如何处理?大型Java项目是否有很多循环依赖项?

我对这个问题的回答是,尽可能少地拥有一些项目。