Пространства имен и структуры папок в решениях c #: как должны быть организованы папки на диске? - PullRequest
14 голосов
/ 30 декабря 2008

Прежде всего, давайте согласимся, что пространство имен должно соответствовать структуре папок и что каждый языковой артефакт должен быть в своем собственном файле.

(см. Должны ли папки в решении соответствовать пространству имен? ).

Следующий вопрос - как на самом деле должны быть организованы папки на диске.
Предположим, у меня есть ClassC в пространстве имен A.B.C и ClassD в пространстве имен A.B.C.D.
Предположим также, что каждое пространство имен встроено в свою собственную сборку (проект) и что пространства имен имеют зависимости справа налево в соответствии с принятой передовой практикой (A.B.C.D может зависеть от A.B.C, который может зависеть от A.B, который может зависеть от A). Я ценю, что каждое пространство имен не обязательно должно быть в отдельной сборке, но в общем случае у нас будет несколько пространств имен в отдельных сборках, и мой пример иллюстрирует это.

Я вижу (по крайней мере) два способа создания дерева папок, которые я буду называть «вложенными папками» и «плоскими папками»:

1 - Вложенные папки:

A
--A.csproj

---- A.B.csproj
---- C
------ A.B.C.csproj
------ classC.cs
------ D
-------- A.B.C.D.csproj
-------- classD.cs

OR

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

Вы увидите, что я уже сделал несколько предположений:

  • Каждый файл проекта имеет полное имя (FQN), основанное на пространстве имен.
  • Каждый файл класса использует не FQN

Вложенные папки кажутся более естественными (нам всем нравится иерархия), но в больших решениях может быть немного сложнее:

Когда вы смотрите на свое решение в VS, оно показывает плоский список проектов, а не вложенное представление. Это больше похоже на «плоские папки», поэтому может быть целесообразно организовать папки на диске в соответствии с представлением в VS.

Если вы заглянете в каждую папку на диске, вы увидите артефакты папки для этого проекта плюс подпапку для пространства имен: на примере C:

C
--bin
* 1057 -D, * --obj
--Properties
--A.B.C.csproj
--classC.cs

В зависимости от реального имени D может быть неочевидным, что D - это папка пространства имен, а не организационная папка в пространстве имен C.

Я знаю, что у нас были папки и пространства имен с первого дня в .NET (8 или 9 лет назад) и Java до этого, но, лично говоря, мы, похоже, не пришли к консенсусу по проекту наилучшей практики организация для крупных решений. Мне было бы очень интересно узнать, что вы все думаете.

Спасибо
Michael

Ответы [ 7 ]

8 голосов
/ 31 декабря 2008

Я использую плоский подход. Я нахожу вложенную иерархию слишком сложной для поддержания. Я группирую свои проекты в несколько решений с максимальной возможностью повторного использования и перекрестными ссылками и всегда находил это удовлетворительным Пример (проекты с отступом):

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

и т.д.. и т.д.

Редактировать: удалено бессмысленное замечание

5 голосов
/ 30 декабря 2008

Я не большой поклонник вложенных проектов, поскольку он скрывает проекты глубоко внутри структуры, и если вам нужно повторно использовать этот проект в другом приложении, что вы делаете, копируете / вставляете код? Мне нравится следовать некоторой плоской структуре, но организованной по пространству имен.

Вот как я это делаю:

- 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)

Надеюсь, это имеет смысл!

3 голосов
/ 30 декабря 2008

Я всегда делал вложенную иерархию. Это до боли делает очевидным, куда добавлять новые проекты в существующее решение, и хорошо организовывает пространство имен на диске. Это также делает разграничение пространства имен и проекта более очевидным.

3 голосов
/ 30 декабря 2008

"Прежде всего, давайте согласимся, что пространство имен должно соответствовать структуре папок и что каждый языковой артефакт [sic] должен быть в своем собственном файле."

Забавно, вот как пакеты работают в Java. Я всегда думал, что разрыв связи между пространствами имен и структурой каталогов считался одним из улучшений, которые представил C #. Разве это не правда? (Прости мое невежество, я человек Java.)

2 голосов
/ 02 февраля 2011

Если вы используете вложенные проекты, вы рискуете столкнуться с проблемой Windows MaxPath . Это огромное препятствие для использования вложенных структур. Только представьте, что вы встретились на полпути с этим маленьким Gem, хотя и разработчиком проекта, назвав проекты 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 и правильная офлайновая история)

0 голосов
/ 05 октября 2013

Я предпочитаю плоскую структуру с проектами в корне.

  • MyCorp.Core
  • MyApp.Domain
  • MyApp.Data
  • MyApp.UI
  • MyApp.Test

Внутри них у меня есть различные папки и пространства имен. Я создаю только разные сборки для развертываемых модулей. Маленькие приложения даже не будут иметь такой степени разделения. ИМО это делает вещи простыми. Если я когда-нибудь решу, что у меня есть код, который нужно использовать где-то еще, то достаточно просто разбить его на сборку, если это необходимо, если я следую хорошей практике в области имен.

0 голосов
/ 31 декабря 2008

Я думаю, вам нужно определить точку отсечения, при которой плоский подход больше не работает. Например, если у вас есть типичная 3-уровневая архитектура в небольшом проекте, наличие 3-х проектов на внешнем уровне не проблема. Однако, если у вас несколько десятков, то какое-то группирование помогает сегментировать функциональность и делает все решение более понятным.

...