A .NET Generic Repository Pattern With Implementations
I previously blogged about the repository pattern and .NET implementations. Here are the links to those old posts:
Since that time, I have zeroed in on a fairly robust implementation of the repository pattern. I have used this implementation on a number of projects. The number of changes to the underlying interfaces and the NHibernate concrete implementation have slowed down. I find this generic repository implementation very useful and hope that you will also. I have posted the repository code on Github.
For the sake of keeping all the documentation in one place, I will be posting additional info in the Github repository also. The repository pattern implementation abstracts away the details of the persistence and ORM layer. This has advantages and disadvantages. The reason I like the pattern is two fold:
- Provides a consistent interface to the higher level layers of the application.
- Allows the persistence layer to be faked for testing.
Example Usage
Here is an example usage:
// Create an instance of the session factory. This is typically done // once and cached. DbSessionFactory is a concrete implementation // of IDbSessionFactory using a variety of ORMs (e.g. NHibernate, // EF...etc). // IDbSessionFactory dbSessionFactory = new DbSessionFactory(connectionString) // Create a session. This represents a database transaction. // using( IDbSesseion session = dbSessionFactory.Create()) { // Create a repository. // IKeyedRepository<Guid, Person> repo = session.CreateKeyedRepository<Guid, Person>(); // Perform actions on the repository // Person person = new Person {Id = Guid.NewGuid(), FirstName = "Bob", LastName = "Cravens" }; repo.Add(person); // Commit the transaction. // session.Commit(); }
Typically the IDbSessionFactory is created once at the start of the application. The concrete implementation of this interface would most likely use your favorite ORM on top of your favorite database. The Github repository currently provides two concrete implementations: NHibernate and an in-memory fake. You can use the fake for automated testing.
Conclusion
Visit the Github source and let me know if you see improvements or if you find this useful. I would like to add a few more implementation for some of the other popular ORMs. If you want to contribute an implementation please let me know.
Hi Bob,
I’m interested in Entity Framework implementation but after run test project it fail almost case. I notice that you implement on EF3.5 from connection string.
I’m try to change connection string to 4.0 but it still fail for all repository test case.
Could you please use latest EF4.1?
Thanks,
Mac
Hi Mac,
I will certainly look at moving to EF4.1. I need to be a bit careful and evaluate how that will affect my other projects. Realistically, I won’t get an opportunity until this weekend. In the meantime, if you stumble upon any hints to make it work please feel free to share.
Thanks.
Bob
Hi Bob,
it is almost 4 years later now, have you got any chance to update it to use EF4.1?
I am waiting for that fix since years now.
Bob,
After checking your implementation I saw that the only way to get an entity is by it’s TKey (the key). There is no “simple” way to get a Person using the first and last name as keys.
Also, that the consumer of the repository has to know the type of the key (which IMHO, is to know a lot about how the entity is persisted).
For the first issue I added a “IQueryable FindBy(Expression<Func> predicate);” on the IRepository (I can send you the changes)…
The second issue, too much info revealed… well I haven’t figured out yet how to hide it.