Какой должна быть масштабируемая микросервисная структура слоя DAL на платформе .net?

Пишу дипломный проект веб-сервиса на .net core. Пытаюсь выстроить масштабируемую архитектуру.
На данный момент в проекте есть единая база данных на orm EntityFramework, обернутая в репозитории, и веб-апи с полным доступом ко всем репозиториям. Есть библиотека DAl.Client, которая оборачивает логику http запросов к апи и предполагается для использования в других сервисах.
Таким образом структура сервиса базы данных выглядит следующим образом:
  1. DAL - проект с контекстом и репозиториями
  2. DAL.Entities - проект с сущностями, чтобы другие микросервисы не тянули контекст и репозитории
  3. DAL.SqlServer - проект для миграций
  4. DAL.API - Апи с контроллерами
  5. DAL.Client - Проект в веб-репозиториями, общающийся с апи

Репозиторий базы данных и веб-репозиторий реализуют один общий generic интерфейс, который декларирует основные crud операции над указанной сущностью. Только бд репозиторий общается с ef core, а веб-репозиторий с DAL.API.

И есть несколько других микросервисов, использующих базу данных. Я использую внедрение зависимостей для получения нужных мне сервисов в конструкторе классов. Было очень удобно регистрировать веб-репозиторий следующим образом:
builder.Services.AddHttpClient<IRepository<CloudResource>, WebRepository<CloudResource>>
                (configureClient:
                client => { client.BaseAddress = new Uri($"{builder.Configuration["DatabaseAPI"]}/Resource/"); });

А затем так же удобно получать его в сервисе:
public CloudService(IRepository<CloudResource> repository)
 {
       _repository = repository;
 }

При разработке этого проекта я следовал видеоуроку Павла Шмачилина. Как я понял, такая структура обеспечила полную независимость domain сервисов, потому что они принимают интерфейсы, а реализация настраивается в конфигурации внедрения зависимостей. И мне это показалось правильным. Таким же образом я реализовал сервис облачного хранилища и сервис отправки email сообщений. Благодаря интерфейсам, я могу легко подменить поставщика облачного хранилища в файле Program.cs в своем domain сервисе:
builder.Services.AddHttpClient<ICloud, YandexCloudProvider>();


Моя проблема состоит в том, что мне нужны репозитории бд с дополнительными операциями по выборке из навигационных свойств или сортировке. И я создавал такие репозитории, наследовал их от generic и расширял. Но, чтобы пользоваться расширенной логикой, в моем domain service в конструкторе надо запросить именно этот класс, а не интерфейс, тк он не декларирует расширяемую логику. Таким образом я нарушаю принцип слабой связанности и единственное решение, которое я вижу - это создать интерфейс для такого репозитория по типу IExtendedUserRepository.
Но мне нужно реально много таких репозиториев, неужели правильным решением будет создавать под каждый репозиторий интерфейс в проекте с интерфейсами?

Тот же вопрос относится к взаимодействию ui и domain сервисов. Допустим у меня есть AuthService, RegisterService, CloudService и т.д. Неужели для того, чтобы независимо их использовать в ui надо под каждый сервис создать интерфейс? А как быть с DTO, которые предоставляют эти сервисы? Нужно создавать их копии в клиентском проекте, чтобы избежать связанности?

Допускаю, что делаю всё совсем не так. Посоветуйте, пожалуйста, где можно почитать про это. Где можно посмотреть на пример веб-сервиса с хорошей архитектурой. Обычно я нахожу какие-то поверхностные объяснения и структуры, которые подвергаются критике в комментарии, но никто не объясняет как действительно нужно сделать. Заранее спасибо!
  • Вопрос задан
  • 339 просмотров
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы