Note that there are some explanatory texts on larger screens.

plurals
  1. POWhere to put global rules validation in DDD
    text
    copied!<p>I'm new to DDD, and I'm trying to apply it in real life. There is no questions about such validation logic, as null check, empty strings check, etc - that goes directly to entity constructor/property. But where to put validation of some global rules like 'Unique user name'?</p> <p>So, we have entity User</p> <pre><code>public class User : IAggregateRoot { private string _name; public string Name { get { return _name; } set { _name = value; } } // other data and behavior } </code></pre> <p>And repository for users</p> <pre><code>public interface IUserRepository : IRepository&lt;User&gt; { User FindByName(string name); } </code></pre> <p>Options are:</p> <ol> <li><em>Inject repository to entity</em></li> <li><em>Inject repository to factory</em></li> <li><em>Create operation on domain service</em></li> <li><em>???</em></li> </ol> <p>And each option more detailed:</p> <p><strong>1 .Inject repository to entity</strong></p> <p>I can query repository in entities constructor/property. But I think that keeping reference to repository in entity is a bad smell.</p> <pre><code>public User(IUserRepository repository) { _repository = repository; } public string Name { get { return _name; } set { if (_repository.FindByName(value) != null) throw new UserAlreadyExistsException(); _name = value; } } </code></pre> <p>Update: We can use DI to hide dependency between User and IUserRepository via Specification object.</p> <p><strong>2. Inject repository to factory</strong></p> <p>I can put this verification logic in UserFactory. But what if we want to change name of already existing user?</p> <p><strong>3. Create operation on domain service</strong></p> <p>I can create domain service for creating and editing users. But someone can directly edit name of user without calling that service...</p> <pre><code>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); } } </code></pre> <p><strong>4. ???</strong></p> <p><strong>Where do you put global validation logic for entities?</strong></p> <p>Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload