На каком уровне я должен объявлять перечисления?

#c# #architecture #enums #n-tier-architecture #n-layer

#c# #архитектура #перечисления #n-уровневая архитектура #n-слой

Вопрос:

У меня есть проект C # N-Layer, который имеет 5 уровней: 1-Инфраструктура 2-Домен 3-AppService 4-Распределенный сервис 5-Презентация

Я хочу использовать перечисления в своем проекте. но я не знаю, какой слой их описывает. У меня есть две идеи по этому поводу.

1- объявляйте перечисления в домене и передавайте по сети с помощью WCF DataContract.

2. объявите перечисления в проекте библиотеки классов (например, в общем слое) и создайте его как dll и используйте его во всех слоях.

Помогите мне выбрать один.

Комментарии:

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

Ответ №1:

Я бы поделился своим мнением относительно этой проблемы:

  • Стратегия 1: Доменный уровень определяет перечисление AddressType (имеющий Home, Work …). Сервисный уровень определяет другое перечисление AddressTypeDto со всеми значениями Home, Work …), и они фактически отображаются из AddressType ==> AddressTypeDto . На уровне представления AddressTypeDto также будет использоваться тип.

  • Стратегия 2: создайте layer ( not really a layer ), который содержит общие типы перечислений, и используйте его на разных уровнях из домена / службы / презентации

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

S2: он сохраняет независимость домена / службы / представления всех уровней, но требует их в зависимости от «общей» dll.

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

Комментарии:

1. Хороший ответ. Я иду с вами. Но, как вы сказали, стратегия 2 более эффективна и СУХА. С точки зрения DDD, вы можете использовать его в домене и приложении.

Ответ №2:

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

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

Если приложение и домен будут их использовать, объявите их в домене и передайте значение по сети.

Ответ №3:

Если это нужно использовать только в каком-то определенном слое, то объявите его в этом слое. Если вы хотите использовать его во всех слоях, тогда он должен быть объявлен в каком-то общем слое, и ссылка должна быть добавлена ко всем слоям, которые его используют.

Ответ №4:

Я лично работал над решением oniony-DDDish, и наличие повторяющихся перечислений и картографов во ВСЕХ слоях чертовски утомительно и никогда не может показаться чистым. Мое решение состояло в том, чтобы иметь все перечисления на уровне домена, а затем, как только данные поступают на внешние уровни (ну, кроме уровня службы приложений, конечно), все это становится приведением int. Подумайте об этом: зачем вам все еще нужно перечисление? Предполагается, что у вас должна быть вся логика на уровне домена, вы не должны делать что-то вроде ‘if (bar.type == types.foo)’ вне уровня домена, это просто анти-шаблон. Если вам действительно нужно значение enum снова в другом слое, просто объявите дубликат перечисления и приведите его обратно… Обычно это может происходить в тестовой сборке.

Комментарии:

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

Ответ №5:

В многослойных решениях каждый слой должен зависеть только от слоя под ним. Например, если вы работаете с использованием DDD, у вас, вероятно, будет это

Уровень представления (должен зависеть от уровня приложения) Уровень приложения (должен зависеть от уровня инфраструктуры) Инфраструктурный уровень (должен зависеть от уровня домена) Уровень домена (не должен зависеть ни от каких слоев)

Итак, в основном перечисления обычно являются частью домена, и если вы не хотите сопоставлять, сопоставлять, сопоставлять, то вам следует добавить дополнительные зависимости к уровням представления и приложения (зависят от домена). Если вы хотите сохранить свою архитектуру в чистоте, то все, что вы можете сделать, это — map . Лично мне не нравится сопоставлять перечисления, поскольку, если нечего сопоставлять, вам придется изобрести новый тип перечисления или создать исключение. Оба решения не так понятны, как хотелось бы.

Обновить

Также рассмотрите возможность использования классов перечисления

https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types