Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Onion Architecture - Repository Vs Service?

I am learning the well-known Onion Architecture from Jeffrey Palermo. Not specific to this pattern, but I cannot see clearly the separation between repositories and domain services. I (mis)understand that repository concerns data access and service are more about business layer (reference one or more repositories).

In many examples, a repository seems to have some kind of business logic behind like GetAllProductsByCategoryId or GetAllXXXBySomeCriteriaYYY.

For lists, it seems that service is just a wrapper on repository without any logic. For hierarchies (parent/children/children), it is almost the same problem : is it the role of repository to load the complete hierarchy ?

like image 754
Cybermaxs Avatar asked Sep 07 '12 11:09

Cybermaxs


People also ask

What is repository in onion architecture?

The repository is not a gateway to access Database. It is an abstraction that allow you to store and load domain objects from some form of persistence store. (Database, Cache or even plain Collection). It take or return the domain objects instead of its internal field, hence it is an object oriented interface.

Is repository a service layer?

Repository layer is implemented to access the database and helps to extend the CRUD operations on the database. Whereas a service layer consists of the business logic of the application and may use the repository layer to implement certain logic involving the database.

What is Repository Service pattern?

Overview. The Repository-Service pattern breaks up the business layer of the app into two distinct layers. The lower layer is the Repositories. These classes handle getting data into and out of our data store, with the important caveat that each Repository only works against a single Model class.

What is infrastructure repository?

The Repository Infrastructure (RI) is designed to allow different kinds of users (researchers, academics, technicians, museum users, web users, etc) to store, query and retrieve digital objects which have been produced by digi- tizing physical objects or by processing other digital objects.


2 Answers

The repository is not a gateway to access Database. It is an abstraction that allow you to store and load domain objects from some form of persistence store. (Database, Cache or even plain Collection). It take or return the domain objects instead of its internal field, hence it is an object oriented interface.

It is not recommended to add some methods like GetAllProductsByCategoryId or GetProductByName to the repository, because you will add more and more methods the repository as your use case/ object field count increase. Instead it is better to have a query method on the repository which takes a Specification. You can pass different implementations of the Specification to retrieve the products.

Overall, the goal of repository pattern is to create a storage abstraction that does not require changes when the use cases changes. This article talks about the Repository pattern in domain modelling in great detail. You may be interested.

For the second question: If I see a ProductRepository in the code, I'd expect that it returns me a list of Product. I also expect that each of the Product instance is complete. For example, if Product has a reference to ProductDetail object, I'd expect that Product.getDetail() returns me a ProductDetail instance rather than null. Maybe the implementation of the repository load ProductDetail together with Product, maybe the getDetail() method invoke ProductDetailRepository on the fly. I don't really care as a user of the repository. It is also possible that the Product only returns a ProductDetail id when I call getDetail(). It is perfect fine from the repository's contract point of view. However it complicates my client code and forces me to call ProductDetailRepository myself.

By the way, I've seen many service classes that solely wrap the repository classes in my past. I think it is an anti-pattern. It is better to have the callers of the services to use the repositories directly.

like image 66
nwang0 Avatar answered Sep 17 '22 17:09

nwang0


Repository pattern mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

So, repositories is to provide interface for CRUD operation on domain entities. Remember that Repositories deals with whole Aggregate.

Aggregates are groups of things that belong together. An Aggregate Root is the thing that holds them all together.

Example Order and OrderLines:

OrderLines have no reason to exist without their parent Order, nor can they belong to any other Order. In this case, Order and OrderLines would probably be an Aggregate, and the Order would be the Aggregate Root

Business logic should be in Domain Entities, not in Repository layer , application logic should be in service layer like your mention, services in here play a role as coordinator between repositoies.

like image 30
cuongle Avatar answered Sep 20 '22 17:09

cuongle