Как работать с MVC ViewModel — модель предметной области — объект в контроллерах и службах MVC

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

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

Проблема заключается в том, что в приложении MVC у нас есть представление для «начальной настройки», в котором используется модель представления, которая в конечном итоге охватывает несколько ограниченных контекстов (с использованием шаблона IUnitOfWork в Entity Framework 6). Следовательно, это представление должно писать в бизнес-контекст и в контекст ролей.

Модель предметной области будет иметь модель Business и модель Address, а также несколько других моделей в более крупном графе объектов.

ViewModel — это плоская упрощенная модель этих двух и других моделей предметной области:

public class InitialSetupViewModel
{
    string BusinessName{get;set;}
    string Street{get;set;}
    string Street2{get;set;}
    string State{get;set;}
    string ZIP{get;set;}
    ...
}

Эта ViewModel должна сопоставляться с моделями предметной области, что мы и делаем с помощью Automapper.

controller внедряет службу домена:

public class SetupController : Controller
{
    private readonly IMaintenanceService service;

    public SetupController( IMaintenanceService maintenanceService = null )
     {
        service = maintenanceService;
    }

    public void Create(...????....)
    {
        service.CreateBusiness(..?.);
    }

}

Проблемы:

  1. Служба не может знать о InitialSetupViewModel, так что же нужно передать службе?

  2. Служба должна знать о BusinessDbContext и RolesDbContext. Поэтому я должен вызвать SaveChanges() для обоих, что превосходит цель иметь один IUnitOfWork. Нужно ли мне создавать еще одну UnitOfWork, включающую как бизнес-объекты, так и ролевые объекты?

Я не думаю, что оправданно объединять эти два IUnitOfWorks в один только для того, чтобы это представление MVC работало. Но каково решение?

Спасибо!


comment
Ваш метод действия Create на контроллере примет вашу модель представления, которую вы затем преобразуете в DTO и передадите ее своей службе.   -  person Vsevolod Goloviznin    schedule 02.12.2014
comment
Для меня тот факт, что одна аппликативная транзакция охватывает несколько ограниченных контекстов, указывает на запах дизайна. Существуют различные способы апостериорной связи между агрегатами, возможно, принадлежащими разным BC, но транзакция должна, насколько это возможно, модифицировать только один агрегат.   -  person guillaume31    schedule 02.12.2014


Ответы (1)


Всегда трудно иметь твердое мнение о домене, которого вы не знаете, но вот оно:

  1. Как уже отмечалось, Controller должен взять на себя ответственность за сопоставление между моделями представления и предметной области, DTO или чем-то еще. В качестве входных данных может использоваться экземпляр InitialSetupViewModel, но детали реализации могут различаться.

  2. Это правда, что ремоделирование домена может быть правильным выбором, если вам нужно иначе нарушить границы ваших ограниченных контекстов. Однако, сосредоточившись только на шаблоне Unit of Work, я не совсем понимаю ваши колебания.

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

    При этом следует не ориентироваться на то, как выглядит ваше представление, а на то, что является «истинным» в вашей модели (ях) предметной области, и вместо того, чтобы иметь дело только с наборами объектов предметной области, ваш домен, вероятно, должен описать подходящие агрегаты.

Может быть, даже можно хранить каждый объект домена с отдельными транзакциями (единицами работы), т.е. если их синхронизация не требуется - например. это все еще хорошо, если (или, возможно, даже желательно, чтобы) неспособность сохранить Business не мешает Roles пройти или наоборот. На самом деле, я думаю, можно даже утверждать, что если ограниченные контексты на самом деле определены правильно, это должно иметь место.

Я надеюсь, что эти комментарии помогут.

Мартин Фаулер о единице работы и Агрегаты.

person Oskar Lindberg    schedule 05.12.2014