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


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

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

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

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

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

相反,我没有发现这种情况的优势。

所以,我的问题是:

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

更新:

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

更新2:

所有三个答案都提供了有价值的信息,但我只能选择一个我正在选择Doc的评论,以评估如何确定DAL项目的数量。 我还链接到我刚发现的其他问题,这些问题有相关信息: 这里 和 这里。 我也建议阅读 本文


4312
2017-07-06 20:40


起源

这听起来像很多项目,但也许应用程序足够复杂,需要这种复杂程度。什么阻止你只有一个主要的解决方案,只是从其他项目引用编译的程序集? - Robert Harvey♦
也许这属于programmers.stackexchange。 - AShelly
关于此类大型解决方案的编译时间的快速提示:查看Scott Hanselmans关于启用的帖子 parallel build 在Visual Studio中: hanselman.com/blog/... - RoelF


答案:


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

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

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

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


9
2017-07-06 21:23



是的,这些是.NET项目。正如我在我的问题中更新的那样,我不是在谈论创建一个单独的项目,而是关于如何定义程序集的“单一责任”方面。我的意思是,我可以在我的设计中定义X dll的责任是“处理所有数据访问”,在这种情况下,我将为所有DAL设置一个项目。但这个定义是否过于宽泛? - Mike
至于避免循环依赖,我同意这是一个很好的论据。但是,我确实觉得如果一个人真的认真对待,那么在类级别分析代码耦合的工具会更合适。毕竟,人们可以拥有一个编译非常好的解决方案,并且每个项目中仍然有一堆紧密耦合的类。 - Mike
例如,如果你的DAL有一个DLL是好还是坏,很大程度上取决于你的DAL的样子。如果您的DAL反映了关系数据库,并且您的数据库中只有一个数据模型/模式,您的每个应用程序都使用它,那么一个DLL可能没问题。如果您有多个模型,它们之间没有直接关系,可能在不同的模式或数据库中,并且您的每个应用程序只访问其中一个模型,那么拆分DAL可能是个好主意。 - Doc Brown


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

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

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

如果将所有项目混合到单个项目中,则不会发生这种情况。如果你跑,你肯定可以发现这一点 DSM软件 在你的代码上,但imo让你的编译器来帮助你更安全。

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

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

我知道C#有 内部 关键字,但有时人们会在不考虑它的情况下将其声明为公开。拥有它的名称是一种更强大的方法,因为它需要更多的工作才能完成这个课程 上市

使用非常庞大的软件的其他方法是插件方式,因此它将使您的构建时间更短。它总是带你的价格。你可以查一下 OSGI 为了那个原因。


1
2017-07-06 21:05



您对API的引用让我觉得我们可能会遇到一些问题。我认为如果你有一个只有同一层中其他程序集使用的类的程序集,那些程序集可以被合并 - 不一定,但至少要讨论。毕竟,您被迫创建一个现在可供所有图层使用的公共界面,即使它不应该。 - Mike


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

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

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


1
2017-07-07 16:31





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

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

这将确保: - 构建时间更快 - 您拥有项目所需的确切项目数量 - 您已经记录了为什么要创建特定项目的原因(需要它满足哪些需求)

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


1
2018-06-12 08:42