I have an asp .net MVC application and recently started implementing the repository pattern with a service validation layer, much like this.
I've been creating one repository/service for each model that I create. Is this overkill? Instead, should I create one repository/service for each logical business area that provides CRUD for many different models?
To me, it seems like I'm either cluttering the project tree with many files or cluttering a class with many methods. 6 one way half dozen the other. Can you think of any good arguments either way?
The main purpose of the repository pattern is to isolate the data access layer and business logic.In Asp.Net MVC model is used to interact with the Data Access layer and Controller for performing Data access operation. The controller is responsible for passing data to the view.
The Repository Design Pattern is one of the most popular design patterns to achieve such separation between the actual database, queries, and other data access logic from the rest of the application.
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.
Use Mediator Pattern Combined with CQRS One approach is to create query and command objects. There's an article by Jimmy Bogard that he suggest preferring query objects over repositories. He also created a library called MediatR which is a Mediator implementation for . Net.
Generally, if you're using a "true" Repository Pattern, as opposed to other persistence layers (e.g. ActiveRecord or DAO's), you should aim to identify your domain aggregates, and create one repository per aggregate.
What does that mean? Well, it depends a lot on your app, but generally there are objects which are naturally 'parents' of other objects, or which are part of a related transaction.
I think the canonical example is an ecommerce system in which you have a concept of an order, and in an order you have orderlines each orderline is some product and a quantity, and so on.
In that case, the Order object is one of the system's aggregate roots and an OrderRepository is created.
The thing to remember in that case is that there's some relationship (implied or otherwise) between a order and its orderlines and so on. So the C-UD parts of "CRUD" on the Repository should generally just be one method each, and should generally just take in an instance of that aggregate root object and operate on it (.e.g. repo.Save(order)). Other possible params might be there, but that depends on your impl.
IN fact, you can often solve most of the C-UD part w/ inheritance (i.e. make a RepositoryBase that implements them using some known logic about what shoudl happen for your particular persistence scheme).
So that leaves us the R part of CRUD. In this case is where you might get a ton of query methods (GetById; GetByName; GetByCustomerName, etc) if you choose to go the query method route. Some folks prefer, espeically for simple apps, exposing a linq-based interface (e.g. an IQueryable GetAll()) that can then have Where clauses applied. YMMV depending on your underlying persistence on that one, but it's a solid shot for simple apps, esp. if you expect your persistence provider to support linq directly.
Lastly, many folks actually separate out the query part via one implentation or another of the Command Query Responsibility Separation pattern, which says the interfaces for persisting and querying should be different. IN that case, you'd have a Repo that just has basic CRUD (GetById, GetAll, Save, Delete) ops and another class of some sort which queries things based on your app's intentions.
Hope that helps.
Paul
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With