首先,让我们同意命名空间应该匹配文件夹结构,并且每个语言工件应该在它自己的文件中。
(见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,它可以依赖于A)。我感谢每个命名空间不必在一个单独的程序集中,但在一般情况下,我们将在单独的程序集中有一些名称空间,我的示例说明了这一点。
我可以看到(至少)两种创建文件夹树的方法 - 我称之为“嵌套文件夹”和“平面文件夹”:
一个
--A.csproj
--B
---- A.B.csproj
----Ç
------ A.B.C.csproj
------ classC.cs
------ d
-------- A.B.C.D.csproj
-------- classD.cs
OR
一个
--A.csproj
A·B
--A.B.csproj
A.B.C
--A.B.C.csproj
--classC.cs
A.B.C.D
--A.B.C.D.csproj
--classD.cs
你会看到我已经做了一些假设:
嵌套文件夹似乎更自然(我们都喜欢层次结构),但在大型解决方案中导航可能有点困难:
当您在VS中查看解决方案时,它会显示项目的平面列表,而不是嵌套视图。这看起来更像是“平面文件夹”,因此在磁盘上组织文件夹以匹配VS中的视图可能是有好处的。
如果查看磁盘上的每个文件夹,您将看到该项目的文件夹文件加上命名空间的子文件夹:以C为例:
Ç
--bin
--D
--obj
--properties
--A.B.C.csproj
--classC.cs
根据D的真实姓名,D可能并不明显是命名空间文件夹而不是C命名空间中的组织文件夹。
我知道我们在.NET(8或9年前)和Java之前的第一天就有文件夹和命名空间,但是,就个人而言,我们似乎没有就最佳实践项目达成共识组织大型解决方案。我真的很想知道你们都在想什么。
感谢
迈克尔
答案 0 :(得分:8)
我使用平面方法。我发现嵌套的层次结构太难维护了。我将我的项目分组到几个解决方案中,并考虑到最大的可重用性和交叉引用,并始终认为这是令人满意的。示例(项目缩进):
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
等。等
编辑:删除废话评论
答案 1 :(得分:5)
我不是嵌套项目的忠实粉丝,因为它将项目深埋在结构内部,如果你需要在另一个应用程序中重用该项目,那么你做了什么,复制/粘贴代码? 我喜欢遵循某种扁平结构,但是按命名空间组织。
我就是这样做的:
- 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)
我希望这是有道理的!
答案 2 :(得分:3)
“首先,让我们同意命名空间应该匹配文件夹结构,并且每个语言工件[sic]应该在它自己的文件中。”
很有趣,这就是Java在Java中的工作方式。我一直认为打破命名空间和目录结构之间的联系被认为是C#引入的改进之一。这不是真的吗? (原谅我的无知,我是一个Java人。)
答案 3 :(得分:3)
我一直在做嵌套层次结构。它使得将新项目添加到现有解决方案的位置变得非常明显,并使您的命名空间在磁盘上得到很好的组织。它还使命名空间与项目的划分更加明显。
答案 4 :(得分:2)
如果您使用嵌套项目,则可能会遇到触及Windows MaxPath问题的风险。 这对于使用嵌套结构来说是一个巨大的破坏者。想象一下,通过一个开发项目中途遇到这个小宝石,不得不用三个字母的首字母缩写命名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整合和适当的离线故事)
答案 5 :(得分:0)
我认为你需要定义一个平面方法不再有效的截止点。例如,如果您在一个小型项目中有一个典型的3层架构,那么在外层有3个项目就没问题了。但是,如果您有几十个,那么某种分组有助于细分功能并使整个解决方案更容易理解。
答案 6 :(得分:0)
我更喜欢在根目录中包含项目的扁平结构。
在这些内部我有各种文件夹和命名空间。我只为可部署单元创建不同的程序集。小应用程序甚至不会有这么多的分离。 IMO让事情变得简单。如果我确定我需要在其他地方使用代码,只要我遵循良好的命名空间实践,只要我需要,就可以将其分解为程序集。
答案 7 :(得分:0)
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
以上试图证明: