c#解决方案中的命名空间和文件夹结构:应该如何组织磁盘上的文件夹?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/400945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Namespaces and folder structures in c# solutions: how should folders on disk be organised?
提问by Micdev42
First off, let's agree that namespace should match folder structure and that each language artefact should be in its own file.
首先,让我们同意命名空间应该与文件夹结构相匹配,并且每种语言工件都应该在自己的文件中。
(see Should the folders in a solution match the namespace?).
(请参阅解决方案中的文件夹是否与命名空间匹配?)。
The next question is how the folders should actually be organised on disk.
Suppose I have ClassC in the A.B.C namespace and ClassD in the A.B.C.D namespace.
Let's also assume that each namespace is built into its own assembly (project) and that namespaces have dependencies from right to left as per accepted best practice (A.B.C.D can depend on A.B.C which can depend on A.B which can depend on A). I appreciate that each namespace doesn't have to be in a separate assembly but in the general case we will have some namespaces in separate assemblies and my example illustrates that.
下一个问题是如何在磁盘上实际组织文件夹。
假设我在 ABC 命名空间中有 ClassC,在 ABCD 命名空间中有 ClassD。
我们还假设每个命名空间都内置到它自己的程序集(项目)中,并且命名空间根据公认的最佳实践从右到左具有依赖关系(ABCD 可以依赖于 ABC,而 ABC 可以依赖于可以依赖于 A 的 AB)。我很欣赏每个命名空间不必在单独的程序集中,但在一般情况下,我们将在单独的程序集中有一些命名空间,我的示例说明了这一点。
I can see (at least) two ways to create the folder tree – which I'll call “nested folders” and “flat folders”:
我可以看到(至少)两种创建文件夹树的方法——我将其称为“嵌套文件夹”和“平面文件夹”:
1 - Nested folders:
1 - 嵌套文件夹:
A
--A.csproj
--B
----A.B.csproj
----C
------A.B.C.csproj
------classC.cs
------D
--------A.B.C.D.csproj
--------classD.cs
甲
--A.csproj
--B
---- ABcsproj
----Ç
------ ABCcsproj
------ classC.cs
------ d
-------- ABCDcsproj
--------classD.cs
OR
或者
2 – Flat folders:
2 – 扁平文件夹:
A
--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
A
--A.csproj
AB
--ABcsproj
ABC
--ABCcsproj
--classC.cs
ABCD
--ABCDcsproj
--classD.cs
You will see I've made a few assumptions already:
你会看到我已经做了一些假设:
- Each project file has a fully qualified name (FQN) based on the namespace.
- Each class file uses a non-FQN
- 每个项目文件都有一个基于命名空间的完全限定名称 (FQN)。
- 每个类文件使用一个非 FQN
Nested folders seems more natural (we all like hierarchies), but may be a bit harder to navigate in large solutions:
嵌套文件夹看起来更自然(我们都喜欢层次结构),但在大型解决方案中导航可能有点困难:
When you look at your solution in VS, it shows a flat list of projects rather than a nested view. This looks more like “flat folders” so there may be merit in organising the folders on disk to match the view in VS.
当您在 VS 中查看您的解决方案时,它会显示项目的平面列表而不是嵌套视图。这看起来更像是“平面文件夹”,因此在磁盘上组织文件夹以匹配 VS 中的视图可能是有益的。
If you look in each folder on disk you will see the folder artefacts for that project plus the sub folder for the namespace: taking C as an example:
如果您查看磁盘上的每个文件夹,您将看到该项目的文件夹 artefacts 以及命名空间的子文件夹:以 C 为例:
C
--bin
--D
--obj
--Properties
--A.B.C.csproj
--classC.cs
ç
--bin
--D
--obj
--properties
--ABCcsproj
--classC.cs
Depending on D's real name it may not be obvious that D is a namespace folder rather than an organisational folder in the C namespace.
根据 D 的真实姓名,D 是命名空间文件夹而不是 C 命名空间中的组织文件夹可能并不明显。
I know we've had folders and namespaces from day one in .NET (8 or 9 years ago) and Java before that, but, personally speaking, we don't appear to have come to a consensus on best practice project organisation for large solutions. I'd be really interested to find out what you all think.
我知道我们从 .NET(8 或 9 年前)和 Java 的第一天起就有文件夹和命名空间,但就个人而言,我们似乎没有就大型项目组织的最佳实践达成共识解决方案。我真的很想知道你们的想法。
Thanks
Michael
谢谢
迈克尔
回答by duffymo
"First off, let's agree that namespace should match folder structure and that each language artifact [sic] should be in its own file."
“首先,让我们同意命名空间应该与文件夹结构相匹配,并且每个语言工件 [sic] 都应该在它自己的文件中。”
Funny, that's how packages work in Java. I always thought that breaking the link between namespaces and directory structure was considered one of the improvements that C# introduced. Is that not true? (Forgive my ignorance, I'm a Java person.)
有趣的是,这就是包在 Java 中的工作方式。我一直认为打破命名空间和目录结构之间的联系被认为是 C# 引入的改进之一。那不是真的吗?(原谅我的无知,我是 Java 人。)
回答by Robert C. Barth
I have always done the nested hierarchy. It makes it painfully obvious where to add new projects to an existing solution and keeps your namespaces nicely organized on disk. It also makes the deliniation of namespace versus project more obvious.
我一直在做嵌套层次结构。这使得在现有解决方案中添加新项目的位置变得非常明显,并在磁盘上很好地组织了命名空间。它还使得命名空间与项目的划分更加明显。
回答by Ricardo Villamil
I'm not a big fan of nested projects, since it buries projects deep inside a structure and if you need to reuse that project in another application then what do you do, copy/paste the code? I like to follow somewhat of a flat structure but organized by namespace.
我不是嵌套项目的忠实粉丝,因为它将项目深埋在结构中,如果您需要在另一个应用程序中重用该项目,那么您会怎么做,复制/粘贴代码?我喜欢遵循某种平面结构,但按名称空间组织。
This is how I do it:
这就是我的做法:
- DataHelpers\
---Factory\
---DataAccess\
---...
- Components\
--- EmailProcessor\
--- ErrorLogger\
- Desktop\
--- WindowsApp1\
- Services\
--- WindowsService1\
--- WindowsService2\
- WebApps\
--- WebApp1\
--- WebApp2\
Now, inside each major application I have, for example:
现在,在我拥有的每个主要应用程序中,例如:
- 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)
I hope that makes sense!
我希望这是有道理的!
回答by user39603
I use the flat approach. I find a nested hierarchy too hard to maintain. I group my projects into several solutions, with maximum reusability and cross-referencing in mind, and always found this satisfactory. Example (projects are indented):
我使用平面方法。我发现嵌套层次结构太难维护。我将我的项目分成几个解决方案,考虑到最大的可重用性和交叉引用,并且总是觉得这令人满意。示例(项目缩进):
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
etc. etc.
等等等等
Edit: removed nonsense remark
编辑:删除废话
回答by Dmitri Nesteruk
I think you need to define a cut-off point where the flat approach no longer works. For example, if you have a typical 3-tier architecture in a smallish project, having 3 projects on the outer level is no problem. However, if you have a few dozen, then some sort of grouping helps segment functionality and makes the whole solution more understandable.
我认为您需要定义一个分界点,在该分界点上平面方法不再有效。例如,如果您在一个小型项目中有一个典型的 3 层架构,那么在外层有 3 个项目是没有问题的。但是,如果您有几十个,那么某种分组有助于细分功能并使整个解决方案更易于理解。
回答by Microsoft Developer
If you use the nested projects you run the risk of hitting the windows MaxPathissue. This is a huge deal breaker for ever using nested structures. Just imagine meeting this little Gem half way though a dev project, having to name VS projects with 3 letter acronyms just so as not to hit MaxPath. An MS bug ending up as the inspiration for the names of your assemblies. What a joke that would be. Working with a flat structures is much better all round.
如果您使用嵌套项目,您可能会遇到 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.
You could create a separate directory for the test projects or as above and have them all together which is easier to manage when adding to source control i.e. Subversion (TFS is better in many ways save for the fact it needs Explorer integration not just VS integration and a proper off-line story)
您可以为测试项目或如上所述创建一个单独的目录,并将它们放在一起,这样在添加到源代码管理即 Subversion 时更易于管理(TFS 在许多方面都更好,因为它需要 Explorer 集成,而不仅仅是 VS 集成和一个合适的离线故事)
回答by Fred
I prefer a flat structure with projects in the root.
我更喜欢在根中有项目的扁平结构。
- MyCorp.Core
- MyApp.Domain
- MyApp.Data
- MyApp.UI
- MyApp.Test
- 我的公司核心
- 我的应用程序域
- 我的应用程序数据
- 我的应用程序界面
- 我的应用程序测试
Inside of these I have various folders and namespaces. I only create different assemblies for deployable units. Small apps won't even have this amount of separation. IMO this keeps things simple. If I ever decide that code I have needs to be used elsewhere, it's easy enough to break it into an assembly if needed, as long as I've followed good namespacing practices.
在这些里面我有各种文件夹和命名空间。我只为可部署单元创建不同的程序集。小应用程序甚至不会有这种分离量。IMO 这让事情变得简单。如果我决定我的代码需要在其他地方使用,只要我遵循良好的命名空间实践,如果需要,很容易将其分解为程序集。
回答by tb-mtg
12 Years on, is there any definitive or best practice answer on this question?
12 年过去了,是否有关于这个问题的明确或最佳实践答案?
I would like to use the Nested folders structure, however given that you:
我想使用嵌套文件夹结构,但是考虑到您:
"agree that namespace should match folder structure and that each language artefact should be in its own file."
“同意命名空间应该与文件夹结构相匹配,并且每种语言人工制品都应该在自己的文件中。”
How would project A.B.C.csprojfolder structure look if it extended code from other namespaces, for example:
如果它扩展了来自其他命名空间的代码,那么项目ABCcsproj文件夹结构会是什么样子,例如:
- grand-parent: A.csproj
- parent: A.B.csproj
- child A.B.C.D.csproj
- external namespaces System.Linqor Microsoft.Extensions.Logging
- 祖父母:A.csproj
- 父级:ABcsproj
- 儿童ABCDcsproj
- 外部命名空间System.Linq或Microsoft.Extensions.Logging
Perhaps something like:
也许是这样的:
/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
Above is trying to demonstrate:
以上是试图证明:
- A folder with a lone Underscore (_) with no text following would substitute as an empty namespace & new root for all external namespaces.
- Folders with Underscore(s) (__A) & (_B) followed by text substitutes as a level up in the tree/hierarchy of the current project. 1 level per underscore
- 带有单独下划线 (_) 且后面没有文本的文件夹将替换为所有外部命名空间的空命名空间和新根。
- 带有下划线 (__A) 和 (_B) 的文件夹后跟文本替换为当前项目的树/层次结构中的一个级别。每个下划线 1 个级别