views:

546

answers:

3

After going through some tutorials on asp.net mvc the repository pattern came up and the example was with one table, the dinners table. Basically the set up was to create an interface and then a concrete class which implemented the interface and program off the interface in the controller class. The Interface has your typical crud methods. Does an interface for each type have to be created if you are going to use this pattern. For instance there was a GetList method with a Dinner type. What if you have 10 different types that you need to perform crud functionality on? does this mean 10 interfaces with 10 concrete classes just for the benefit of being able to switch the db technology down the road? I am trying to figure out how to apply this pattern to a standard 3 - tier architecture (Object Layer, Business Logic Layer, Data Access Layer).

Thanks.

+2  A: 

This may be a bit more involved than what you are looking for, but you could check out the sample Northwind app in S#arp Architecture.

The repositories are in the Northwind.Core project.

Also the benefit of using repositories and DI is not so you can switch the underlying database technology at some future date. Rather, you get the ability to write unit tests where you can mock and fake the services (that have been defined by interfaces) in the tests for the classes that they depend on.

Bramha Ghosh
A: 

It's up to you whether you create a generic IRepository class with CRUD methods that can be used for any table vs. unique repository classes for each table.

This is the kind of question I would ask when trying to decide:

"Should every repository support Create, Read, Update and Delete?"

I have chosen to use custom repository classes so that my interfaces are more explicit. For example I have tables of lookup data that I do not allow inserts, updates or deletes on. The repository for those tables contain only Get methods. This provides me with a cleaner design but at the cost of a bit more work.

Todd Smith
Are you creating an interface and then a concrete class for those get only repositories?
TampaRich
Yes. It makes unit testing and IoC easier.
Todd Smith
+6  A: 

This is the way i usually do it in my implementations.

A generic interface, IEntityRepository which defines your basic CRUD structure. In my implementations i define the following members:

  1. Insert
  2. Update
  3. Delete
  4. Get
  5. GetPaged
  6. GetAll
  7. Find (This one is using a predicate builder to build the where clause)

I create another interface IMyentityRepository which inherits IEntityRepository. This allows me to add any entity-specific members and still be able to use DI when i need to. I then create my sealed class MyentityRepository which inherits IMyentityRepository and implements all members.

When you use Dependency Injection you can register your interface (IMyentityRepository) for concrete type of MyentityRepository.

In my case, i wasn't actually done. I created a service layer on top of the repository to encapsulate it and expose it in a more general way. For instance, say you want to create an account for your user which may involve more work than simply creating a database record. In your service, you'd have a member called CreateUser() which may call multiple repository members in its implementation. My service layer is built in the same was as my repository layer. I have IEntityService for common CRUD members, IMyentityService for entity-specific members and MyentityService for implementation. MyentityService class would require an instance of IMyentityService (You can inject it with your IoC framework of choice) Your service layer may also do validation and any business logic. I do validation in controllers. Well, technically, i invoke it my controllers and get the result that i can then write to ModelState.

Hope that helped a little.

Sergey