Репозиторий, конвейер, бизнес-логика и модель предметной области - как мне их совместить? - PullRequest
14 голосов
/ 20 мая 2011

Я разрабатываю N-уровневое приложение и столкнулся с трудностью, решение которой у вас может быть.Уровень представления - MVC.

Мой ORM выполняется с использованием LinqToSQL - это отдельный проект, который обслуживает репозитории.

Каждый репозиторий имеет интерфейс и как минимум 1 конкретную реализацию.

Репозитории имеют следующие методы: FindAll(), Save(T entity), Delete(int id)

FindAll() возвращает IQueryable некоторого типа, что означает, что он возвращает запросы, к которым я могу применить фильтры.

Выполнено сопоставление ORMиспользуя методологию Database First, в которой сначала создавались таблицы, а затем классы создавались SQL Metal.

Я добавил слой Pipeline, который работает с репозиториями.Это применяет дополнительные фильтры к запросам.Например, OrderRepository.FindAll().Where(o => o.CustomerId == 10)

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

На этом этапе я хотел бы переместитьдо уровня BusinessLogic, но я больше не хочу работать с моделями сущностей, я хочу преобразовать модель сущностей в модель предметной области.Это означает, что я могу добавить проверку модели и использовать эту модель на уровне представления.Модель не может быть определена в проекте MVC, так как она будет зависеть от уровня представления, так что это нет.

Я вполне уверен, что бизнес-логика (поведение) и модель должны храниться отдельно от конвейера,слой данных и представления.Вопрос в том, где?

Например, конвейер имеет три метода: 1. FindByCustomerId 2. FindByOrderId 3. FindBySomethingElse

Все эти методы возвращают IQueryable of Order.Мне нужно преобразовать это в модель предметной области, но я не хочу делать это для каждого метода, так как он не будет поддерживаться.

Мне кажется, что эта модель достаточно надежна и масштабируема.Я просто не вижу, что является лучшим местом для сопоставления сущностей с моделью домена и наоборот.

Спасибо

Ответы [ 5 ]

13 голосов
/ 21 мая 2011

Прежде всего, если вы применяете принципы доменного управления, у вас не должно быть слоя BusinessLogic в вашем приложении.Вся бизнес-логика должна жить внутри вашей доменной модели.

Но с помощью LinqToSQL добиться этого довольно сложно, поскольку он не поддерживает отображение наследования и вам придется иметь дело с частичными классами, чтобы поместить бизнес-логику в ваш домен.Поэтому я настоятельно рекомендую сначала перейти с LinqToSQL на NHibernate или Entity Framework Code. В этом случае вам также не придется преобразовывать модель персистентности в модель вашего домена и наоборот.

Если вы все еще хотитечтобы сделать преобразование, вы можете взглянуть на Automapper

12 голосов
/ 01 июня 2011

С точки зрения домена, вам понадобится фабрика для преобразования вашей «сущности базы данных» в сущность модели домена.

Когда вы думаете о превращении «объектов базы данных» в объекты модели домена в конце вашего конвейера, вы должны понимать, что после преобразования в объекты модели домена (проекция) вы не сможетеиспользуйте функциональность IQueryable, поскольку проекция вызовет выполнение вашего дерева выражений.Например, если вы вызываете FindAll для своей сущности базы данных клиентов, а затем конвертируете IQueryable в (или проецируете его на) сущность домена клиента, которую он будет выполнять (запрашивая содержимое всей вашей таблицы).

8 голосов
/ 06 июня 2011

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

В проекте Mvc есть все ваши обычные объекты (контроллеры, ViewModels, представления, помощники и т. Д.).Довольно просто.Все взгляды строго типизированы.Кроме того, мои модифицированные шаблоны T4, которые генерируют Controllers, Views и ViewModels.

В проекте Business Model у меня есть все мои бизнес-объекты и правила. Включены интерфейсы, которые определяют функциональные возможности хранилищ данных.Вместо того, чтобы иметь одно хранилище для каждого бизнес-объекта / таблицы, я предпочитаю группировать мои по функциональности.Все объекты, относящиеся к блогу, находятся в одном репозитории, в то время как все объекты, относящиеся к фотогалерее, находятся в отдельном репозитории, а регистрация может быть в третьем.

Здесь можно разместить слой конвейера.

В проекте Data я реализую эти интерфейсы хранилища данных.Вы можете использовать Linq2SQL без необходимости использовать частичные классы.Расширение этих частичных классов Linq2SQL означает, что вы привязали свой ORM к своей доменной модели.То, что вы действительно не хотите делать.Вы хотите оставить эти сгенерированные классы данных в домене данных.Вот пример выбора Linq2SQL, который возвращает объект BusinessModel.

from t in Table
where t.Field == keyField
select new BusinessModel.DataObject
{
  Id = t.Id,
  Field1 = t.Field1,
  Field2 = t.Field2
}

На вашем месте я бы посмотрел на EntityFramework 4.1 с использованием подхода CodeFirst или использовал бы NHibernate.Любой из них отобразит вашу модель данных в модель предметной области.Затем, чтобы сопоставить модели домена с моделями представления, вы можете использовать AutoMapper или написать собственный код или написать шаблон T4, который сгенерирует код отображения для вас.

Вы можете взять код, сгенерированный файлом dbml, какотправная точка для ваших бизнес-объектов.

3 голосов
/ 07 июня 2011

В дополнение к комментариям xelibrion вы можете взглянуть на LightSpeed ​​для ваших потребностей ORM.В настоящее время вы используете LinqToSQL, поэтому вы должны найти Lightspeed очень простым, поскольку он использует ту же идею.

http://www.mindscapehq.com/products/lightspeed

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

0 голосов
/ 20 мая 2011

Все эти методы возвращают IQueryable из Порядок. Мне нужно преобразовать это в модель предметной области, но я не хочу делать это для каждого метода, как это не будет mainteinable.

Это неверная оценка, которая, вероятно, не позволяет вам найти правильное решение.

...