Re[4]: Альтернативы EF Core
От: Spinifex Россия https://architecture-cleaning.ru/
Дата: 15.08.17 18:15
Оценка: +1
Здравствуйте, IT, Вы писали:

S>>У ORM есть вся необходимая информация чтобы не вытаскивать это наружу. В этом плане NHibernate сделан очень грамотно. В итоге для NHibernate style мы получаем unitOfWork следующего вида:


IT>И хибернейт и UoW уже не раз предавались анафеме и не только здесь на сайте. Персистентность объектной модели приложения привлекательна только паначалу, особенно после просмотра учебных роликов. Жизнь она оказывается немного сложнее.


Давайте конкретнее выясним где учебные ролики и реальные проекты имеют косяки.
Возьмем типичную реализацию метода веб сервиса. Предположим у нас метод работает с какими-то там доменными сущностями типа Пользователь. Нужно при создании пользователей создавать какие-то там группы, отправлять некие сообщения, а также оповещать сотрудников на этаже в этой организации что появился новый пользователь. Это все придумано для примера, поэтому не будем вдаваться в подробности.
Что мы в таком случае имеем:

Первым делом это UserWebController который отвечает за работу по http — проверил входные параметры, прописал урл, кинул BadRequest и все на этом. Далее он дергает сервис.
UserService содержит в себе логику по координации вызовов из разных репозиториев. Первым делом он создает транзакцию или сессию или единицу работы здесь названий много.
А также логирование и прочие какие-то обвесы типа отпаравки правильных сообщений в правильные микросервисы.
public sealed class UserService {
...
public void CreateUserInDistributedSystem(...){
    using(var unitOfWork = new UnitOfWork())
    {
        var userRepository = new UserRepository(unitOfWork);
        var messageRepository = new MessageRepository(unitOfWork);
        var organizationRepository = new OrganizationRepository(unitOfWork);
        ...
        if(userRepository.CheckExistanceOfAdminUsers()){
            var adminGroup = userRepositroy.CreateAdminGroup();
            messageRepositroy.SendMessageForGroup(adminGroup, "Welcome message")
        }
        var user = userRepository.CreateAdminUser();
        var usersOnTheFlat = organizationRepository.GetUsersOnTheFlat();
        foreach(var organizationUser in usersOnTheFlat){
            messageRepository.SendMessageForUser(organizationUser, $"{user.Name} was created");
        }
    }

UnitOfWork это во первых транзакция, я всегда могу ее отролбечить, всегда могу из контекста достать данные без обращения в базу. Репозитории содержат в себе логику по доступу к данным. Иногда специфичную для данного ОРМ. Типа QueryOver, желательно Linq (но не всегда это возможно), иногда даже Dapper. Но такие случаи нужно избегать и до последней возможности стараться писать на linq.
Репозитории могут понадобится в других сервисах. Например, получение пользователей для данной организации на данном этаже происходит не только при оповещении о создании нового пользователя, но и при пожарной тревоги.
Отправка сообщений — много где нужна, во многих сервисах. И даже создание пользователя может происходить неявно также во многих случаях.
Таким образом мы имеем четкую структуру. Каждый из классов имеет свою обязанность. Смена ОРМ происходит максимально легко. Конечно это не просто подмена файлика — методы репозиториев и быть может даже сервисов нужно будет переписывать.
Теперь вопрос. Что с этой схемой не так? Как выглядит работа с linq2db? Скорее всего это файл сервиса на 2000 строк где все вперемешку.

P.S. Здесь говорили что менять ОРМ часто не надо. Забавно, но изначальный пост был как раз про это. ОРМ вам нужно поменять, например, при переходе на Core. И вы хотите минимизировать правки.
Отредактировано 15.08.2017 18:30 Nikita Lyapin . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.