0
votes

My application is broken down into several assemblies.

The MyProject.Infrastructure assembly contains all of the Domain objects such as Person and Sale as well as interfaces repositories such as IPersonRepository and ISaleRepository.

The MyProject.Data assembly contains concrete implementations of these repositories.

The repositories pull data from a database and instantiate new domain classes. For example, IPersonRepository.GetPersonByNumber(customerNumber) will read a customer from the data source, create a new Person class, populate it and return to the caller.

I'm now starting to see cases where adding some methods to my Domain classes might make sense, such as Person.UpdateAddress(address).

Is it ok to put this method on my Person class as a virtual method, and then create derived classes inside my Data layer which override those methods to provide the desired functionality?

I want to make sure I'm not going breaking any DDD conventions.

I know I also have the option of putting these methods on the repository - e.g. IPersonRepository.UpdatePersonAddress(person, address).

2
Why are you data access classes implementing the domain classes? The domain should encapsulate the data access, hide it from the using code. - Oded
The domain classes would remain bare and not be concerned with persistence. The data classes would be overriding the domain classes and providing the necessary persistence functionality. - NoPyGod
I think i've sort of figured it out now. A simple method like Person.FirstNamePlusSurname, which performs operations using properties of the class, would be ok to have on the Domain class. However something which has to make an additional query to the database, such as Person.UpdateAddress, would best live on the repository as Person.UpdatePersonAddress, because only the repository should be concerned with how data is saved/loaded to and from the database, where as the domain class should be concerned with itself only. - NoPyGod
UpdateAdress is not a good DDD name. Did the user move? Then user.MovedToNewAddress(address). - jgauffin

2 Answers

0
votes

Person.UpdateAddress should definitely be in your domain, not in your Repository. UpdateAddress is logic and you should try to avoid logic inside your repository. If you're working with Entity framework there is no need for 'data classes'.

0
votes

Most ORMs have change trackers which will persist related entities automatically when you persist the main one (provided you declared the right relations in the mapping configuration), so you don't need UpdatePersonAddress() on your Repository. Just do whatever you want to do at the object level in Person.UpdateAddress(address) without thinking about persistence, this is not the place for that.

What you need though is an object that will be called in execution context-aware code to flush changes to the persistent store when you think it's time to save these changes. It might be a Unit of Work that contains the Entity Framework DbContext, for instance.