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, и на этом уровне вы делаете вызов в хранилище.