Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a repository dependent on another repository

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?

like image 245
MrGrumpy Avatar asked May 08 '15 07:05

MrGrumpy


People also ask

Why should I use repository pattern?

The Repository pattern makes it easier to test your application logic. The Repository pattern allows you to easily test your application with unit tests. Remember that unit tests only test your code, not infrastructure, so the repository abstractions make it easier to achieve that goal.

What is repository layer?

Repository layer is added between the domain and data mapping layers to isolate domain objects from details of the database access code and to minimize scattering and duplication of query code. The Repository pattern is especially useful in systems where number of domain classes is large or heavy querying is utilized.

What is repository design pattern?

Repository Design Pattern separates the data access logic and maps it to the entities in the business logic. It works with the domain entities and performs data access logic. In the Repository pattern, the domain entities, the data access logic, and the business logic talk to each other using interfaces.

Is there a way to include a git repository inside dependencies manager?

While the use of dependencies manager is really encouraged, because they do so much more than simply including remote repositories (minimum / maximum versions requirements, dependencies downloading, incompatibilities...), it exists several other solutions to include git repositories inside a main git repository.

How to nest one Git repository in another?

git subtree is a good option to nest one repository in another. It does not require users to learn extra commands to access the nested repositories. You can learn more about this feature by reading About Git subtree merges.

What is the use of the other repository?

The other repository has its own history, which does not interfere with the history of the current repository. This can be used to have external dependencies such as third party libraries for example.

How do I move a remote repository to a new branch?

Pull the newest of the remote into your dotfiles. Note that when pushing, you changed the remote to your own fork and you are pushing to a new branch, in the example above, it's issue-xxxx . If you are working on a GitHub issue, you may want to use the issue number as the branch name. git subtree is a good option to nest one repository in another.


1 Answers

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

  • try to keep your business logic in one place, do not spread part of it to UI, part of it to repositories, part to database (sometimes due to performance issues you have to do some logic on database side, but thats an exception)
  • never let repositories reference other repositories, repository is a very low-level component of your application with very simple responsibilities

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.

like image 116
Sergey Berezovskiy Avatar answered Oct 09 '22 11:10

Sergey Berezovskiy