Я новичок в DDD, и я пытаюсь применить его в реальной жизни. Нет вопросов о такой логике проверки, как проверка нуля, проверка пустых строк и т.д., Которая идет непосредственно на конструктор/свойство сущности. Но где поставить проверку некоторых глобальных правил, таких как "Уникальное имя пользователя"?
Итак, у нас есть объект User
public class User : IAggregateRoot
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
// other data and behavior
}
И хранилище для пользователей
public interface IUserRepository : IRepository<User>
{
User FindByName(string name);
}
Параметры:
- Вложение репозитория для объекта
- Вставить репозиторий в factory
- Создать операцию в службе домена
- ???
И каждый вариант более подробный:
1. Внедрение репозитория для объекта
Я могу запросить репозиторий в конструкторе/свойстве объектов. Но я думаю, что сохранение ссылки на репозиторий в сущности - плохой запах.
public User(IUserRepository repository)
{
_repository = repository;
}
public string Name
{
get { return _name; }
set
{
if (_repository.FindByName(value) != null)
throw new UserAlreadyExistsException();
_name = value;
}
}
Обновление. Мы можем использовать DI, чтобы скрыть зависимость между User и IUserRepository через объект Specification.
2. Инъекционный репозиторий factory
Я могу поместить эту логику проверки в UserFactory. Но что, если мы хотим изменить имя уже существующего пользователя?
3. Создание операции в службе домена
Я могу создать службу домена для создания и редактирования пользователей. Но кто-то может напрямую редактировать имя пользователя без вызова этой службы...
public class AdministrationService
{
private IUserRepository _userRepository;
public AdministrationService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void RenameUser(string oldName, string newName)
{
if (_userRepository.FindByName(newName) != null)
throw new UserAlreadyExistException();
User user = _userRepository.FindByName(oldName);
user.Name = newName;
_userRepository.Save(user);
}
}
4.???
Где вы помещаете глобальную логику проверки для объектов?
Спасибо!