Название класса и пространство имен имею одно и тоже имя
Допустим, у меня сборка содержит интерфейс и реализацию одного сервиса.
В итоге структура проекта выглядит так:
Dal->Models->SomeModel
Abstract->Services->ISomeService
Concreate->Services->SomeService
И хочется вот назвать сборку SomeService и корневым пространством имен сделать SomeService.
Все бы хорошо, но в других сборках приходится извращаться и писать полный путь к типу...
Вот как правильно выбирать пространство имен в таких случаях?
Ответы (2 шт):
Ну, во-первых, класть один сервис в одну сборку это как правило слишком сильно переусложнять себе жизнь, но да, проблема понятна, тоже сталкивался с таким.
А во-вторых, решение простое: вместо того, чтобы корневым пространством имён сделать SomeService вам нужно назвать его Contracts (там где вы говорите об Abstract->Services->ISomeService), мы такие штуки отдельно собираем в пакеты на тимсити, это логично и понятно - контракты на это, на то. И вот там уже не так критично, один интерфейс или сто в контракте - главное, что имя подбирается легче. Ну вот у нас допустим одно из типовых правил - это CompanyName.ProjectNameContracts или CompanyName.ProjectName.SomeContracts
С Concrete у меня как правило вообще вопрос такой не стоит - всё запихивается в проект с именем Application, обычно нет нужды делать более чем одной реализации, но чисто гипотетически я могу привести пример на реализацию в Ef, Dapper, Ado: примените префиксы Ef, Dapper, Ado перед названием своего сервиса. То есть найдите то, чем различаются у вас эти реализации и это сделайте префиксом. А если реализация у вас пока/всегда одна - тогда используйте слово Default в качестве префикса по умолчанию.
Итого, предлагаю например такой вариант: сборку называем SomeService, в ней делаем папки/неймспейсы Models, Contracts и DefaultImplementation. (Можно и другие варианты вывести, это вот то, что сразу просится)
Кроме того, я много смотрел примеров на Mediatr и мне даже чем-то нравится иногда то, что дописываешь имя неймспейса и через точку имя класса, вот например я у себя экспериментировал:
один раз указан using:
using Transactions = Usol.Wally.Application.Transactions;
А потом в названиях пишем Transactions.List.Query или Transactions.Create.Command -- и это в принципе немного напоминает один из вариантов -- как если бы мы делали длинные уникальные имена тип CreateCommand или CreateTransactionCommand.
Так что иногда такие точки-разделители вполне нормально смотрятся, главное сгруппировать логично (у меня в этом примере сгруппировано не вокруг сервисов, а вокруг отдельных сущностей).
Нужно руководствоваться Framework Design Guidelines:
DO NOT use the same name for a namespace and a type in that namespace.
Да, всё верно, не называйте неймспейс и тип тем же именем.
Шаблон для именования оттуда же:
<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]
В вашем случае, имхо, фичей являются сервисы. Значит пространство имён может выглядеть как-то так:
namespace IluxaCorp.IluxaProduct.Services
Внутри него определены интерфейсы, классы и подпространства моделей.