I'd like to apply Domain Driven Design principles in my project but couldn't determine what I should do with the business logic of dependent models.
For example, suppose this scenario:
I have Person
and Car
domain models. Each Person is suitable to buy certain cars from db based on age/budget/preferences/etc. In my model, I'd like to have a List of Cars (SuitableCars
) which are appropriate for this Person.
public class Person
{
public List<Car> SuitableCars {get; set;}
}
But in order to do that right now, I have to call a service method (GetSuitableCarsForPerson
) to fetch data from db (DI with repository), run my (sometimes fairly complicated multi-model dependent) custom logic and get the cars.
public class PersonService : IPersonService
{
private IRepository _repo;
public PersonService(IPRepository repository)
{
_repo = repository;
}
public List<Car> GetSuitableCarsForPerson(Person person)
{
// business goes here right now.
}
}
So the declaration of SuitableCars
property will become:
private IPersonService _personService;
public List<Car> SuitableCars
{
get
{
// I have to inject a PersonService in my model. Bad practice?
return _personService.GetSuitableCarsForPerson(this);
}
}
AFAIK, Services should be kept thin(ref) and are used to let you put Not-DomainModel-Related business in them. But I believe logic like what I have described belong to the model itself.
So, how to handle these kinds of logics where I should access relevant models and do various custom validations/filters to get the appropriate data?
Thank you.
It seems like the definition of the set of suitable cars for a person depends on factors outside of the person model and can vary independent of the person. The set of suitable cars depends not only on the person's preferences but also on the set of all cars. The set of cars varies independently of the person and so the set of suitable cars for a given person is a cache of an operation that determines the set of suitable cars. These observations indicate that a repository or domain service should return sets of suitable cars for a person and the association between a person and the set of suitable cars should not be expressed on the person model directly. What could be an appropriate association to express directly on the person model is the set of cars that person specified as preferred models because in this case the person is the "owner" of this data. In DDD, it is acceptable to express associations directly in models or through the use of repositories and selecting a specific approach depends on several factors, some of which are outlined above. Take a look at this series of articles for an in-depth treatment of how to design your models.