Я таки поделил репозиторий на 2 слоя: низкие и высокие функции. Будем рассматривать на примере получения юзера
1. Принимает сырой тип гуид, возвращает асинхронного ридера, у которого окружением является DbContext, а результатом исполнения является DAO модель. Короче действительно низкоуровенщина
2. Теперь окутаем функцию из [1] пункта в домен. А именно, отныне аргумент — не сырой гуид, а доменная модель UserId , а возвращаемое значение тоже теперь не UserDao , а доменная модель User. Очевидно, что при парсинге UserDao в User могут возникнуть ошибки — их тоже возвращаем в качестве неуспешного результата. Окружением всё также является только DbContext
3. (Только что написал) Функция уже практически самого высокого слоя — принимает доменный айди юзера, а возвращает опшн юзера (есть/нет), и если нет, то залогировать это дело. Тут уже окружением является "общим", которое содержим как контекст, так и логгер. Однако находится на слое application layer, что немного выходит из стандартной модели