寻求关于Microsoft Visual Studio解决方案和项目命名约定的建议

7

看起来没有任何经过验证的最佳实践指导您如何设置解决方案、项目和它们输出的程序集。微软似乎在 VS.net 时代尝试过,但他们已经放弃了这个内容。对于我读到的每种方法,都有另一种声称相反更好的方法,或者只关注“如果微软能够…”的帖子,但实际上并没有提供解决方案。

似乎有许多方法可以做到这一点,它们似乎都适用于不同情况下的各种团体,因此我想问一下您使用的约定以及为什么它们对您的情况有效。

我希望这将为不同情况、小型开发团队和项目到大型分散开发团队和项目提供几个良好的约定。

您使用哪些约定来...

  • 给你的解决方案命名,为什么?
  • 给你的项目命名,为什么?
  • 给你的程序集命名,为什么?
  • 知道何时创建新项目或添加到现有项目中,为什么?
  • 知道何时将解决方案拆分为较小的解决方案,为什么?
  • 知道何时将项目拆分为多个项目,为什么?

需要明确的是,在这些答案中,为什么和如何同样重要。在这里和其他地方发布了许多关于如何的答案,很少有人说他们为什么使用一种约定而不是另一种。

3个回答

3
那是一个非常广泛的问题,但是是个好问题。我将从一个简单的结构开始介绍ASP.Net Web项目(MVC外观完全不同)。
对于解决方案的命名,并不是很重要。我倾向于为特定目的创建解决方案,并将现有项目添加到解决方案中。如果您的解决方案超过15个项目(只是一个大概的数字),请考虑将其中一些项目添加为参考。大多数人不需要同时处理超过15个项目。
对于项目命名,这对我来说很重要。
// class library that supports the site itself and abstracts
// more complicated UI logic into a separate place
Company.ProductName.Web;

// website
Company.ProductName.Web.UI;

// main business object library for product
//
// of course, you can have as many of these as needed.
Company.ProductName;

我在项目中尽量使用足够的文件夹,以便在不滚动解决方案资源管理器的情况下轻松查看文件夹中的所有文件。
我的典型Web项目如下所示。请注意,大小写不同以表示命名空间/可编译资源与非命名空间/不可编译资源之间的区别。
- client(css、javascript) - config(私有、自定义配置文件,如果有的话) - Content(主页面、ASPX和ASCX,分成逻辑文件夹) - Handlers(ASHX等) - images - MSBuild(构建脚本) - WebServices(这些应该仅是与相关网站直接相关的小型服务。否则,请将它们分成单独的项目)。
我开始越来越多地使用部分类来创建全面的类,这些类可以做很多事情而不会使代码混乱。例如,我最近创建了一个Web服务,其唯一目的是向客户端返回JSON,但是为了更好地组织逻辑,该逻辑分散在几乎十个部分类中。
希望这能给你一个好的开始。

你如何将其扩展到具有大量模块的大型企业级应用程序?你如何管理公司名称更改? - Rodney S. Foley
首先,实现版本控制和源代码管理。如果您更改公司名称,请创建产品的新版本,并在解决方案上执行大规模的查找/替换操作。这并不引人注目,但它是有效的,并且使用版本化方法,您不会破坏依赖于产品的兼容性。关于企业级应用,那是主观的...最大的挑战将是使您的UI应用程序项目保持稳定。对于Web,您可以在多个项目中使用SOA;对于Windows,表单/控件继承可帮助拆分大型UI项目。 - Tim M.
坦白地说,除非有巨大的业务驱动力来进行重命名,否则我会将其放在优先级列表的较低位置。许多公司(包括微软)会购买产品并保留传统名称,而不是处理麻烦。 - Tim M.
你如何在遵循Robert C. Martin的打包原则(REP,CCP,CRP,ADP,SDP和SAP)的同时保持自己的方法平衡? 这6个原则在过去14年中被许多人反复提及,作为管理软件包(又称组件,.Net项目)的方法。然而,虽然它们解释得很清楚,但只提供了简单的例子,当把它们推广到大型企业级应用程序时,这些原则似乎会导致仅有少量类的小型软件包。 - Rodney S. Foley
@Creepy - 你在那里提出了一系列不容易回答的问题。我建议你发布另一个专注于特定焦点的问题,这样我们可以处理它。简而言之,一个良好组织的项目结构可以并且应该遵循你提到的原则,但其中很多都取决于开发人员的技能和常识。 - Tim M.

2
在我们的情况下,我们将项目名称与我们选择的特定程序集的命名空间保持相同。这样可以很容易地映射出物理文件夹中类文件的位置。例如 - CompanyName.BusinessLine.BusinessServiceCompanyName.Framework.Security。因此,如果开发人员正在查看CompanyName.Framework.Security.Cryptography.cs,他可以立即找到该项目并打开它。

1
Visual Studio的“对象浏览器”使得查找包含给定类的程序集变得简单,无论命名空间是否匹配。 - Brent Arias
我不记得它是否告诉你汇编的位置,例如源代码。 - Pradeep
1
你如何为拥有数十个或数百个模块的大型企业应用程序进行扩展?如果您需要重构跨多个项目和解决方案的主要接触区域,该如何管理项目和解决方案?由于命名空间和项目名称中包含公司名称,您如何管理公司名称更改? - Rodney S. Foley

2
正如Tim所说的那样,这是非常广泛的。需要注意以下几点:
- 一个解决方案通常只是一组项目。例如,许多解决方案可以包含相同的项目。因此,解决方案名称并不太重要,如果你不喜欢解决方案的名称,则可以完全不进行重构而将其丢弃。 - 像Pradeep一样,我倾向于使用它们包含的顶级命名空间为项目命名。"更深层次"的命名空间最终会出现在子目录中,因此Foo.Bar.Baz 命名空间中的类可能位于 Foo.Bar 项目的 Baz 目录中。 - 我倾向于按照以下方式划分项目: - 可重用性元素(例如,一个用于 UI 的程序集,一个用于可重用模型类集合,一个用于可重用的通用工具类集合) - 部署元素(例如,一种用于生产,一种用于测试,成对出现) - 引用元素(例如,如果您有一个常见的程序集 Skeety.Common,其中包含其他类使用的一些接口,则可能会有一个Skeety.Common.Testing程序集,其中包含帮助您测试使用Skeety.Common的类的类型)。这导致了以下规则: - 生产程序集仅能引用其他生产程序集 - 测试程序集仅能引用生产程序集和其他测试程序集 - 测试程序集(包含测试本身的程序集)只能引用生产和测试程序集,而不能引用其他测试程序集 - 不允许循环引用 - 在许多情况下,实际上划分项目并不太重要,但在你解决依赖性层次结构时可以使设计更加清晰(例如,业务逻辑程序集不应该引用 UI 程序集,反之亦然)。 - 有太多项目肯定会减慢工作速度,无论是构建时间还是找出每个东西应该放在哪里。而过少的项目则会使设计变得不够清晰。随着时间的推移,你可能会对如何布局有更多的直觉感受,但我绝不会声称总是知道最佳操作方式 :)

如何扩展这个系统呢?假设你有一个庞大的综合业务套件,并且确保你遵循了DRY和SOLID原则。假设这个套件具有以下高层模块:CRM,ERP,PLM,SCM,SRM等等。它们之间有很多共享代码,并且还有一个共同的用户界面,每个模块都有与其他模块集成的钩子/扩展点。我可以理解为每个模块都可以有解决方案,并且对于这些高层项目来说可能是非常庞大的。 - Rodney S. Foley
@Creepy:在不同解决方案之间共享的代码可以是包含在所有解决方案中的项目中,也可以只是由所有解决方案引用的类库二进制文件中的代码。 - Jon Skeet
谢谢,我似乎在罗伯特·C·马丁的封装原则(REP、CCP、CRP、ADP、SDP 和 SAP)方面找不到平衡的方法。也许我只是过于考虑这个问题了,因为当我看着当前的开发项目并计划下一个开发项目时,它似乎并不是一项容易的任务,并试图考虑以前的开发项目。也许我应该停下来,只关注当前的工作,因为使用 Visual Studio 和 TFS 提供的工具似乎太难去想其他的方式。 - Rodney S. Foley
@Creepy - 我认为作为一名架构师,你越是精通,就越会分析每一个细节,这是一件好事。在规划项目时,确定物理结构往往会引导人们考虑大局,无论是重用、抽象化、可扩展性等等。 - Tim M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接