I've recently been spending time reading up on SOLID principles and decided to seeing how the code base I work with compares.
In some of our code there is a repository (repository A). When a record is to be deleted from the repository A, we also need to delete an associated record from repository B. The original coder has therefore created a dependency to a concrete implementation of repository B. The method in repository A is within a transaction and deletes the record from repository A and then calls the method on repository B to delete the associated data.
My understanding of the S principle is that each object should have only 1 reason to change, but to my repository A has 2 reasons to change? Or am I way off the mark?
Repository should have single responsibility - persist one kind of entity. E.g. employees. If you have to delete some associated records from other repository, it looks like business logic. E.g.
When employee is fired we should remove his work log
And usual place for business logic is a domain services. This service will have both repositories and do all the job:
staffService.Fire(employee)
Implementation will look like
public class StaffService
{
private IEmployeeRepository employeeRepository;
private IWorkLogRepository workLogRepository;
private IUnitOfWorkFactory uowFactory;
// inject dependencies
public void Fire(Employee employee)
{
using(var uow = uowFactory.SartNew())
{
workLogRepository.DeleteByEmployee(employee.Id);
employeeRepository.Delete(employee.Id);
uow.Commit();
}
}
}
So, basic advises
You may wonder what to do if you have employee and it has some nested object which is stored in different database table. If you use that object separately from employee, then everything is as above - you should have separate repository, and some other object (service) which manipulates both repositories. But if you don't use that nested object separately from employee, then employee is an Aggregate Root and you should have only employee repository, which will query both tables inside.