Как да се справим с MVC ViewModel - Domain Model - Entity в MVC контролери и услуги

Ние пишем MVC приложение за поддръжка на данни е част от по-голям проект. Опитваме се да използваме управляван от домейн дизайн DDD. Вече има други въпроси относно това в SO, като тук, тук и тук. Но те не отговарят напълно на въпроса ми.

Имаме и ограничени контексти в слоя данни, тъй като базата данни има 755 таблици. Така създадохме ограничени контексти за бизнес, роли, продукти, клиенти и т.н.

Проблемът, който имаме, е, че в приложението MVC имаме изглед за „първоначална настройка“, който използва ViewModel, който в крайна сметка обхваща множество ограничени контексти (използване на шаблон IUnitOfWork в Entity Framework 6). Следователно този изглед трябва да се съобразява с бизнес контекста и контекста на ролите.

Моделът на домейна ще има Business модел и Address модел и няколко други модела в по-голяма pbject графика.

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.

Контролерът инжектира услугата за домейн:

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. Вярно е, че премоделирането на домейна може да бъде правилният избор, ако откриете, че имате нужда от друго нарушаване на границите на ограничените ви контексти. Въпреки това, като се съсредоточавам само върху модела на единица работа, не разбирам напълно вашето колебание.

    Отговорност на внедряването на единица работа е да следи всички обекти на домейна, които трябва да бъдат синхронизирани в рамките на една транзакция. Няма нищо странно в това един и същи обект(и) на домейн да участва в няколко различни работни единици. Това не означава, че трябва да комбинирате „по-малки“ реализации на единица работа в „по-големи“, когато имате работа с друг тип агрегат, но включвайки както „роли“, така и „бизнеси“ в една единица работа, разбира се.

    Правенето на това не трябва да бъде подтикнато от това как изглежда вашият изглед, а от това, което е „вярно“ в модела(ите) на вашия домейн и вместо да се занимава само с колекции от обекти на домейн, вашият домейн вероятно трябва опишете подходящи агрегати.

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

Надявам се тези коментари да помогнат.

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

person Oskar Lindberg    schedule 05.12.2014