DDD - сервисная специализация

Я пишу мультитенантное решение Platform As A Service и пытаюсь использовать подход DDD. У меня есть базовая функциональность Core, которая является поведением по умолчанию и предоставляет свои сервисы уровню API (приложения). До сих пор все было просто, пока я не начал писать индивидуальные пользовательские функции (отдельные проекты поверх Core). Как расширить базовые сервисы для добавления настраиваемого поведения?

Например, Core оказание услуг:

namespace Core.Services
{
    public class UserService
    {
        private readonly IUserRepository userRepository;

        public User Get(Guid id)
        {
            userRepository.GetById(id);
        }

        public void Update(Guid id, UserStatus newUserStatus)
        {
            userRepository.UpdateStatus(Guid id, newUserStatus);
        }
    }
}

Теперь у меня есть ClientAкто хочет, скажем, периодически переименовывать пользователей в зависимости от их активности:

namespace ClientA.Services
{
    public class UserService // : Core.UserService ?
    {
        public void RenameInactiveUsers()
        {
            // something like
            userRepository.UpdateAll(
                condition: (user) => { user.NotActiveRecently() },
                action: (user) => { user.Name = user.Name + " (inactive)" }
            )
        }

        public void BanSuspiciousUsers()
        {
            userRepository.UpdateAll(
                condition: (user) => { user.SomeSuspiciousFlag },
                action: (user) => { user.Status = UserStatus::Banned }
            );
        }

        // etc
    }
}

Итак, как мне расширить базовые сервисы, оставаясь при этом доступным Get, Update и другие способы повторного использования кода?

Должно ли это быть наследством? Таким образом, мне придется сделать частные репозитории, данные и методы доступными для предков. Кроме того, наследство в DDD препятствует, насколько я знаю.

Или должен для каждого арендатора создать новый UserService, который занимает Core.UserService и выставить идентичный контракт, который приведет ко многим кодам, как

ClientA.UserService.Get(id) { return udnerlyingUserService.Get(id); }?

Может быть, какой-то третий вариант?

1 ответ

Во-первых, не используйте userRepository в службе ClientA, чтобы отделить бизнес от уровня инфраструктуры.

реализация в clientA может быть только простым вызовом службы: Core.userService, и на этом уровне вы делаете вызов в хранилище.

Другие вопросы по тегам