Кратко о том куда помещать Repository в Onion Architeckture и DDD

—

от автора

Привет, Хабр. Хочу рассказать о том куда, на рисунке выше, поместить репозиторий. Еще немного о DI, IoC и структуре проекта. Если вам интересно, то добро пожаловать под кат.

1) Repository работающий с БД это InfrastructureService так же как какой-нибудь EmailSender или EmailService, FileService (обертка над файловой системой который внутри вызывает File.Open(… ) и т. п.) и прочее в этом духе. 2) Serivice это любой класс без состояния. InfrastructureService это анти коррапшн лаер который изолирует вас от файловой системы, библиотеки для работы c SMTP ну и конечно от ORM или библиотеки для работы с Базой Данных и т. п. 3) Repository это паттерн. Его теоретически может реализовать любой класс в любом слое. Например типичный List это Repository который использует в качестве хранилища массив T[] и по сути является ValueObject поэтому относиться к слою Entities. Не каждый класс реализующий паттерн Repository является InfrastructureService и не все InfrastructureService реализуют паттерн Repository. Например: Logger, EmailSender.

Чтобы понять куда помещать абстракции надо вспомнить про Dependency Inversion и Inversion of Control. Согласно им наш ApplicationService может использовать Infrastructure не знаю про том какая у него реализация такими способами как 1) Определять интерфейс, который будет реализовать Infrastructure и взаимодействовать с ним. 2) Просто принимать делегаты вроде Action и Func.

Через интерфейсы:

//Наш InfrastructureService. Сама реализация в слое Infrastructure     interface IRepository     {         int Get();     }      class ApplicationService     {         private readonly IRepository _repository;          public ApplicationService(IRepository repository)         {             _repository = repository;         }          public int GetInt() => _repository.Get();     } 

Через делегаты:

    class ApplicationService     {         private readonly Func<int> _getIntFromDb;          public ApplicationService(Func<int> getIntFromDb)         {             _getIntFromDb = getIntFromDb;         }          public int GetInt() => _getIntFromDb();     } 

Теперь о том как структурировать код. Тут надо рассмотреть два случая: 1) Все разбито по папкам. 2) Все разбито по библиотекам. Подробно о терминологии можно почитать тут.

По папкам в пределах одного приложения

Просто помещаем все наши InfrastructureServices (Repository) в папку Infrastructure.

Пример кода

Game/SnakeGame:

По библиотекам

Помещаем интерфейсы InfrastructureServices (IRepository) в библиотеку ApplicationServices, а реализацию (Repository) в библиотеку Infrastructure.

Выводы

Интерфейс инфраструктурных сервисов (IRepository, IEmailSender) можно поместить в библиотеку ApplicationServices.dll, а их конкретную реализацию (Repository, EMailSender) в библиотеку Infrastructure.dll. Если просто положить IRepository в Infrastructure.dll и взять на него ссылку в ApplicationServices.dll то вместе с IRepository который только нам и нужен к нам прилетят еще и ссылки на EntityFramework, SmtpClient и прочее в этом духе лишнее.

ссылка на оригинал статьи https://habr.com/ru/post/501206/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *