Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Designing repositories for DI (constructor injection) for service layer

I'm building an MVC3 app, trying to use IoC and constructor injection. My database has (so far) about 50 tables. I am using EF4 (w/ POCO T4 template) for my DAC code. I am using the repository pattern, and each table has its own repository. My service classes in my service layer are injected w/ these repositories.

Problem: My service classes are growing in the number of repositories they need. In some cases, I am approaching 10 repositories, and it's starting to smell.

Is there a common approach for designing repositories and service classes such that the services don't require so many repositories?

Here are my thoughts, I'm just not sure which one is right:

1) This is a sign I should consider combining/grouping my repositories into related sections of tables, reducing the number or dependent repositories per service class. The problem with this approach, though, is that it will bloat and complicate my repositories, and will keep me from being able to use a common interface for all repositories (standard methods for data retrieval/update).

2) This is a sign I should consider breaking my services into groups based on my repositories (tables). Problem with this is that some of my service methods share common implementation, and breaking these across classes may complicate my dependencies.

3) This is a sign that I don't know what I'm doing, and have something fundamentally wrong that I'm not even able to see.

UPDATE: For an idea of how I'm implementing EF4 and repositories, check out this sample app on codeplex (I used version 1). However, looking at some of the comments there (and here), looks like I need to do a bit more reading to make sure this is the route I want to take -- sounds like it may not be.

like image 456
Jerad Rose Avatar asked Nov 07 '11 04:11

Jerad Rose


People also ask

What is the difference between the repository pattern and 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 are Repositories and services?

The repository is where the data is stored. The service is what manipulates the data. In a real-world situation comparison, if your money is stored in a vault in a bank, the vault is the repository. The teller that deposits, withdraws, etc is the service.

What is service repository pattern?

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 the repository design pattern?

The Repository pattern. Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.


2 Answers

Chandermani is right that some of your tables might not be core domain classes. This means you would never search for that data except in terms of a single type of parent entity. In those cases you can reference them as "complex types" rather than full-blown entities, and EF will still take care of you.

I am using the repository pattern, and each table has its own repository

I hope you're not writing these yourself from scratch.

The EF 4.1 already implements the Repository Pattern (DbSet), and the Unit of Work pattern (DbContext). The older versions do too, though the DbContext template can easily be tweaked to provide a clean mockable implementation by changing those properties to an IDbSet.

I've seen several tutorial articles where people still write their own, though. It is strange to me, because they usually don't provide a justification, other than the fact that they are "implementing the Repository Pattern".

Writing wrappers for these repositories for access methods like FindById make it slightly easier to access, but as you've seen is a big amount of effort potentially little payback. Personally, unless I find that there is interesting domain logic or complex queries to be encapsulated, I don't even bother and just use Linq directly against the IDbSet.

My service classes in my service layer are injected w/ these repositories.

Even if you choose to use custom query wrappers, you might choose to simply inject the DbContext, and let the service code instantiate the wrappers it needs. You'd still be able to mock your data access layer, you just wouldn't be able to mock up the wrapper code. I'd still recommend you inject less generic ones though, because complex implementation is exactly the type of thing you'd like to be able to factor out in maintenance, or replace with mocks.

like image 120
Merlyn Morgan-Graham Avatar answered Sep 18 '22 11:09

Merlyn Morgan-Graham


If you look at DDD Aggregate Root pattern and try to see you data in this perspective you would realize that many of the table do not have a independent existence at all. Their data is only valid in context of their parent. Most of the operations on them require you to get the parent as well. If you can group such tables and find the parent entity\repository all other child repository can be removed. The complexity of associating the parent child which till now you would be doing in your business layer (assuming you are retrieving parent and child using independent repo) not would be shifted to the DAL

Refactoring the Service interface is also a viable option, and any common functionality can be moved into a base class and\or can be itself defined as a service which is consumed by all your existing services (Is A vs Has A)

like image 33
Chandermani Avatar answered Sep 20 '22 11:09

Chandermani