HimeraSearchDB
Carding_EbayThief
triada
CrackerTuch
d-shop
HimeraSearchDB

НОВОСТИ Кратко о том куда помешать репозиторий в Onion Architeckture и DDD

Bonnie
Оффлайн
Регистрация
12.04.17
Сообщения
19.095
Реакции
107
Репутация
0
g-mdvngslazcpacsfe-hx_pbk-q.png


Привет, Хабр. Хочу рассказать о том куда, на рисунке выше, поместить репозиторий. Если вам интересно, то добро пожаловать под кат.
Во-первых: На КДПВ картинке выше слои разделяют конкретные реализации, а не абстракции т.е. в ApplicationServices слое должные лежать конкретные реализации ваших ApplicationServices. О том куда вы будете помешать ваши абстракции и контракты (интерфейсы, трейты) она не говорит. Во вторых: Repository это InfrastructureService так же как какой-нибудь EmailSender или EmailService, FileService (обертка над файловой системой который внутри вызывает File.Open(… ) и т. п.) и прочее в этом духе. В третьих: InfrastructureService это анти коррапшн лаер который изолирует вас от файловой системы, библиотеки для работы c SMTP ну и конечно от ORM или библиотеки для работы с Базой Данных и т. п. Теперь мы поняли куда помешать реализации (UserService) что собственно и так отображено на картинке в заголовке статьи. Теперь поговорим о том куда помешать контакты (IUserService). Serivice это любой класс без состояния. Чтобы понять куда помещать абстракции надо вспомнить про 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 _getIntFromDb;

public ApplicationService(Func getIntFromDb)
{
_getIntFromDb = getIntFromDb;
}

public int GetInt() => _getIntFromDb();
}



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

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


Просто помещаем все наши InfrastructureServices (Repository) в папку Infrastructure.
Пример кода —
4-5gaquzhbyyxsgpbcl9vnzdh2i.jpeg


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


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


Граф зависимостей:
afj_wr9i3milchswg_fxg2ckyz4.jpeg
 
Сверху Снизу