首先,我们同意名称空间应与文件夹结构匹配,并且每种语言的人工制品都应位于其自己的文件中。
(请参阅Should the folders in a solution match the namespace?。
下一个问题是文件夹应如何实际在磁盘上组织。假设我在A.B.C名称空间中具有ClassC,在A.B.C.D名称空间中具有ClassD。我们还假设每个命名空间都内置于自己的程序集(项目)中,并且按照公认的最佳做法,命名空间从右到左具有依赖性(A.B.C.D可以依赖于A.B.C,而A.B.C可以依赖于A.B,而A.B可以依赖于A)。我感谢每个名称空间不必位于单独的程序集中,但通常情况下,我们将在单独的程序集中包含一些名称空间,我的示例对此进行了说明。
[我至少可以看到两种创建文件夹树的方法-我将其称为“嵌套文件夹”和“平面文件夹”:
A--A.csproj--B---- A.B.csproj - - C------ A.B.C.csproj------ classC.cs------ D-------- A.B.C.D.csproj-------- classD.cs
OR
A--A.csprojA.B--A.B.csproj公元前--A.B.C.csproj--classC.csA B C D-A.B.C.D.csproj--classD.cs
您将看到我已经做了一些假设:
嵌套的文件夹似乎更自然(我们都喜欢层次结构),但是在大型解决方案中可能很难导航:
当您在VS中查看解决方案时,它显示的是项目的平面列表,而不是嵌套视图。这看起来更像是“平面文件夹”,因此组织磁盘上的文件夹以匹配VS中的视图可能有好处。
[如果查看磁盘上的每个文件夹,您将看到该项目的文件夹伪像以及名称空间的子文件夹:以C为例:
C--bin--D--obj-物业--A.B.C.csproj--classC.cs
根据D的全名,可能不是很明显D是C名称空间中的名称空间文件夹而不是组织文件夹。
我知道我们从.NET(八,九年前)和Java的第一天开始就有文件夹和名称空间,但是就个人而言,我们似乎并未就最佳实践项目组织达成共识适用于大型解决方案。我真的很想知道大家的想法。
谢谢迈克尔
我使用固定方式。我发现嵌套层次结构很难维护。我将我的项目分为几个解决方案,同时考虑到最大的可重用性和交叉引用,并始终感到满意。示例(项目缩进):
CompanyName
CompanyName.Core
Class1
Struct2
Enum3
CompanyName.Data
CompanyName.Web
CompanyName.Projects
CompanyName.Projects.Core
CompanyName.Projects.ProjectX
CompanyName.Projects.ProjectX.Core
CompanyName.Projects.ProjectX.Website
CompanyName.Projects.ProjectX.ToolY
等等
编辑:删除废话
我不是嵌套项目的忠实拥护者,因为它会将项目埋在结构内部,如果您需要在另一个应用程序中重用该项目,那么您应该怎么做,复制/粘贴代码?我喜欢遵循某种平面结构,但按名称空间组织。
这是我的方法:
- DataHelpers\
---Factory\
---DataAccess\
---...
- Components\
--- EmailProcessor\
--- ErrorLogger\
- Desktop\
--- WindowsApp1\
- Services\
--- WindowsService1\
--- WindowsService2\
- WebApps\
--- WebApp1\
--- WebApp2\
现在,在我拥有的每个主要应用程序中,例如:
- WindowsService1\
--- WindowsService1\ (this contains all *.cs, bin, obj, etc and .csproj file)
--- Solution\ (this contains the .sln file where you link to other projects like ErrorLogger, etc)
我希望这很有道理!
“首先,我们同意名称空间应与文件夹结构匹配,并且每种语言工件都应位于其自己的文件中。”
很有趣,这就是程序包在Java中的工作方式。我一直认为断开名称空间和目录结构之间的链接被视为C#引入的改进之一。那不是真的吗(请原谅我的无知,我是Java人。)
我一直做嵌套的层次结构。这使得在向现有解决方案中添加新项目的位置变得显而易见,并使名称空间在磁盘上井井有条。这也使命名空间与项目之间的偏差更加明显。
如果使用嵌套项目,则可能会遇到Windows MaxPath问题。对于使用嵌套结构而言,这是一个巨大的突破。试想一下,在开发项目中途遇到这个小Gem,必须用3个字母的缩写来命名VS项目,以免打到MaxPath。一个MS错误,最终激发了程序集名称的灵感。真是个笑话。全面使用平面结构要好得多。
-SouceControlFolderName
-Project1
-Src
-Main
-Company.Project1.AppName
*Company.Project1.AppName.sln
*Company.Project1.AppName.Tests.sln
-Company.Project1.AppName.Common
-Company.Project1.AppName.Common.Tests
-Company.Project1.AppName.Entities
-Company.Project1.AppName.Entities.Tests
-Company.Project1.AppName.Security
-Company.Project1.AppName.Security.Tests
-etc.
您可以为测试项目或如上所述创建一个单独的目录,并将它们放在一起,在添加到源代码控制(例如Subversion)中时,该目录更易于管理(TFS在很多方面都更好,因为它需要与Explorer集成,而不仅仅是VS整合和适当的离线故事)
我认为您需要定义一个不再使用统一方法的截止点。例如,如果您在一个较小的项目中具有典型的3层体系结构,那么在外部级别具有3个项目就没有问题。但是,如果只有几十个,则某种分组有助于分段功能,并使整个解决方案更易于理解。
我更喜欢以项目为根的扁平结构。
在这些文件中,我有各种文件夹和名称空间。我只为可部署单元创建不同的程序集。小型应用程序甚至没有这种分隔。海事组织这使事情变得简单。如果我决定需要在其他地方使用我的代码,只要我遵循了良好的命名间隔惯例,就可以很容易地将它分成一个程序集。
12年以来,在此问题上是否有任何确定的或最佳实践答案?
我想使用嵌套文件夹结构,但是鉴于您:
“同意名称空间应与文件夹结构匹配,并且每个语言伪像应该在其自己的文件中。“
项目A.B.C.csproj文件夹结构如何从其他命名空间扩展代码,例如:
/A // namespace: A
/B // namespace: A.B
/C // namespace: A.B.C
A.B.C.csproj
ClassC.cs
/_ // External Namespace root folder (underscore with no text)
/System // namespace: System
/Linq // namespace: System.Linq
IQueryableExtensions.cs
/Microsoft // namespace: Microsoft
/Extensions // namespace: Microsoft.Extensions
/Logging // namespace: Microsoft.Extensions.Logging
ILoggerExtensions.cs
/__A // namespace: A (Grand Parent folder (2 underscores for 2 levels up)
ClassAExtensions.cs
/B // namespace: A.B (Nested Parent folder)
ClassBExtensionsNested.cs
//Parent Namespace folder (1 underscore for 1 level up)
/_B // namespace: A.B
ClassBExtensions.cs
/D // namespace: A.B.C.D (Child folder)
ClassDExtensions.cs
以上试图证明: