Implement Step-by-Step Generic Repository Pattern in C#

By October 1, 2014C#

It is not a good idea to access the database logic directly in the business logic. Tight coupling of the database logic in the business logic make applications tough to test and extend further. Direct access of the data in the business logic may cause problems such as:

  1. Difficulty completing Unit Test of the business logic
  2. Business logic cannot be tested without the dependencies of external systems like database
  3. Duplicate data access code throughout the business layer (Don’t Repeat Yourself in code)

Without a Repository, an application will be seen as below:

Businesslogic

Repository Pattern separates the data access logic and maps it to the entities in the business logic. It works with the domain entities and performs data access logic. In the Repository pattern, the domain entities, the data access logic and the business logic talk to each other using interfaces. It hides the details of data access from the business logic. In other words, business logic can access the data object without having knowledge of the underlying data access architecture. For example, in the Repository pattern, business logic is not aware whether the application is using LINQ to SQL or ADO.NET Entity Model ORM. In the future, underlying data sources or architecture can be changed without affecting the business logic.

generticrepo2

There are various advantages of the Repository Pattern including:

  • Business logic can be tested without need for an external source
  • Database access logic can be tested separately
  • No duplication of code
  • Caching strategy for the datasource can be centralized
  • Domain driven development is easier
  • Centralizing the data access logic, so code maintainability is easier

Now let’s see how we  can implement a Generic Repository Pattern in C#. We’ll start with creating an Entity class. This class contains one public variable Id, which will represent the identity column of the entity.

Generic Repository Interface of the type IEntity can be created as follows. I have put basic CRUD operations as part of it. Keep in mind that if a particular repository requires additional operations, it can extend the generic repository interface.

We are going to work on the Author table. To represent this, we have created an entity class Author. Author entity class should extend the IEnity class to work with the generic repository.

The entity class is annotated with the Table attribute. You may want to use the FLUENT API for the annotation, however, I am leaving it as is.

To create AuthorRepository, create a class that will implement the generic repository interface IRepository<Author>. I am performing CRUD operations using the Entity Framework. However, you may use any option like LINQ to SQL, ADO.NET etc.  There is nothing much to discuss about implementation of CRUD operations in the AuthorRepository class since it is an easy LINQ to Entity codes to perform the CRUD operations.

The AuthorRepository class is as follows:

That’s all you should do to implement the generic repository pattern. In any application whether the MVC, the WPF or in a Console Application, the implemented generic repository can be used as follows:

Here, I am directly creating instance of the AuthorRepository, whereas you should use a DI container like StructureMap or Unity to create instance of the AuthorRepository for better testability and run time resolve of dependency.

This is all you’ll need to implement the Generic Repository pattern in application.

Happy Coding!


Also published on Medium.

The following two tabs change content below.
  • Pingback: Implement Step-by-Step Generic Repository Pattern in C# | debugmode()

  • straight forward and very good stuff 🙂

  • Hi DJ Sir,
    Is there any special reason to use IEnumerable instead of IQueryable? I prefer using IQueryable since I can query it on the datasource instead of querying in memory records.
    Thanks.

    • Muhammad Abdul Arshad Rana

      It’s good to use IQueryable if you are accessing data from external data source, If it’s in memory then prefer IEnumerable

  • ardalis

    IQueryable is a leaky abstraction. It behaves differently based on whether the underlying data source is EF or some other store, resulting in sometimes unexpected runtime errors in the client code. Also, it tends to encourage putting a lot of query logic in the controller, which frequently becomes duplicated as a result. Better to place common query logic into a repository or specification that can be better tested and reused.

    • I would also say that the implementation proposed does not comply with notion of Unit of Work as it performs save after each operation.

  • ?approve

    Steve Smith
    Chief Technology Officer, Falafel Software @ardalis | ardalis.com | LinkedIn | About.me

  • ardalis

    Programming directly to EF constructs tightly couples the application to EF and (usually) to a database, making it difficult to test the code without having a test database in place. EF also has a huge surface area, so taking a dependency on EF instead of just on a narrowly defined interface violates the Interface Segregation Principle and (again) makes the code more tightly coupled and less maintainable.

    • Pete Weissbrod

      How often have you swapped out EF for another framework? Hiding all database under a single generic interface is in itself an anti-pattern as the application grows in complxity. As the fellow stated below this is leaky abstraction. You dont need generic interface, make multiple interfaces for the different places you need to interact with the database and you get the same testability without the leaky abstraction.
      Even if there was an issue there are frameworks that let you replace entity framework database with in-memory database. Any way you slice it up you are promoting an anti-pattern for all but the most simple of software projects.Im surprised this is endorsed by falafel

      • I agree with Pete. How often does anyone ever swap EF for another Repo. I understand the intent behind the blog post which is a generic repo pattern that can be used across solutions. The truth is a Single generic interface does not fit well with complex, well normalized DBs, it would be better to create specialized interfaces.

      • I agree Pete too, his point is well taken about anyone ever swapping EF for another repository so what’s the point?? Personally, I like the repo pattern because it’s clean and keeps things generic. Not generic for the project itself, but a generic pattern that can be used across different projects. This isn’t really meant for swapping EF for something itself, just to maintain consistency across several solutions.

      • Adam Anderson

        The main point for being able to swap out the data access technology is because of its usefulness in testing, not because customers want to change a part of the application they can’t see or touch. I do agree that a single, generic interface is not going to be a good fit for a sufficiently complex DB.

      • Patrick Dunn

        I understand Pete’s points but I often like it at times because, in my eyes, it reduces complexity and the “gotchas” of ORMs that a lot of people fall into when working on a project with other people – especially those who are not familiar with EF, other ORMs, or data access in general. It’s clean, consistent across projects, and makes the data access code easy to use in a team setting. I don’t see an issue using it in small-medium size projects. Is it the best for every project? No, but that’s why you to evaluate the requirements and use the patterns and practices that fit the project.

        • Pete Weissbrod

          If your assembled team doesnt understand the basic technology they are building thing in then you have greater problems on your hands than this design pattern. My take on it is: if your application realizes some level of success it will naturally grow. The more your application grows the more this generic single interface for all data access will bring forth pain.

          Sorry to respectfully disagree with the whole basis of this post but if you do a little research youll find plenty of research that backs it up

        • Pete Weissbrod

          Come to think of it, if your application is very small then why bother introducing a generic vestige in the first place?

      • ardalis

        The leaky abstraction comment was in fact made by me, and refers to returning IQueryable, not to having a generic Repository. This post is showing how one can do something, it’s not suggesting that one should always do so. There are applications that can benefit from using this approach, as it provides a means of implementing CRUD data access through a single interface without making unit testing of the UI or business layer difficult via tight coupling. For more complex applications, one would probably create multiple specific interfaces. As with anything, it depends on the specific needs of the application, and what may be a “best practice” (or anti-pattern) in one scenario is the opposite in others.

      • Matt

        I have an application which uses EF in one configuration, but also runs on Mono for Linux in others, and Xamarin as well using a SQLite backend. Swapping out frameworks is mandatory in this case.

        There’s never a good reason to not program to an interface. You should be abstracting out any functionality that EF is providing you anyways as part of a good design. If the business logic needs to know what your database is, the design is not correct.

        IMO, the autogenerated classes made by EF are simply too tempting for misuse. I’ve worked in shops where those classes were actually being used all the way to ASP pages, and it guarantees a tightly coupled system.

        • Pete Weissbrod

          Matt the argument is not about whether to employ interfaces. The argument is about if it is a good decision to shoehorn all your database interaction through a single interface known as this generic repository.

          The alternative I’ve been trying to describe (apparently unclear) it is better to define interfaces dedicated for services and operations as opposed to defining whether they happen to use a database or not.

          • Matt

            Ah I see – generally a repository is tied to a type of entity. It doesn’t imply that all DB interaction should be through a single interface – but that CRUD operations for this entity should. Breaking up your database by action rather than state is going to lead to very procedural code.

            If you mean services in a DDD sense, the operation of the database is a dependency of the Repository, to be sure. However the concept of ‘Repository’ is an abstraction of storage as a whole – from a hashmap to a sharded database, it shouldn’t matter to the consumer of the repository.

          • Nissim Levy

            Can you not work with multiple repository interfaces? A repository interface is not dedicated to a specific database or lack thereof – quite the contrary. The data store is in the implementation, not the interface.

      • Simon Ozturk

        I totally agree with Pete, Repository pattern was useful before Entity framework 5. After they introduce Code First, many developer thinks Repo is an extra wrapper. I personally stop using Repository pattern instead using base Entity classes or Interfaces.

  • Ali körabbaslu

    Thank you very much dude;)

  • zakir sheriff

    Great post.. Thanks 🙂

  • Danny Bullis

    Can you quickly define “domain entity”?

  • Pingback: Repository Implementations | @florincoros()

  • April Kroll

    I’ve seen plenty of people calling the generic repository an “anti-pattern,” but I haven’t managed to find a single working example of the alternative. Anyone care to share?

    • Adam Anderson

      I’ve heard that too but also haven’t seen any particularly great examples. I can come up with a few, though. For one thing, restricting your DB access to *only* the generic methods above would be terrible for performance. Either one row by ID or the entire table? If that entire table has hundreds of thousands of rows and/or very wide columns, that will be a horribly inefficient data access pattern. Two possible solutions would be to return a queryable result to let the consumer perform further filtering prior to execution or to introduce a specialized method on the repository. The first solution is also considered bad because it allows data access responsibility to creep into other code and it’s not really testable. A specialized method that accepts specific inputs and is supposed to return a certain kind of result on the other hand keeps data access isolated within the repository and has cleanly defined output, making it testable and mockable. But now you no longer have a generic repository, which is why I would say that a generic repository might make a nice base for specialized repositories, but for any non-trivial application, you will definitely want specialized repositories and not constrain yourself solely to the interactions provided by a generic one.

      • April Kroll

        I agree the specialized repository sounds nice. Problem is, if I knew much about implementing repositories, I wouldn’t need blogs like this.

  • Rafael da Silva Ferreira

    Can I use this model of work to build UWP apps?

  • Martin Mews

    How do you communicate errors back to the client? Sorry but this is a terribly naive implementation and hardly a step by step.

    • Dan

      why should the repository communicate error back to the client? that is a naive comment buddy!

      • ruimpcraveiro

        Because the client (of the repository, not necessarily the frontend) needs to know when something went wrong. That’s why exceptions were invented. Why does it need to know when something went wrong? Either to be able to handle it or, preferably, to give the user some feedback that his transaction wasn’t performed at all.

  • Pingback: Implementing a Generic Repository Pattern C# - Brian VarleyBrian Varley()

  • dg78

    Generic repository ? no, only the interface is generic

    You have a table Author, a class Author and you create a class AuthorRepository.
    If I add a table Book, I must add a class Book (normal) but also a class BookRepository and so on if I have many entities (the real life).

    If you put only one class Repository(T) which works with every entity, you can say Generic but it is not the case here.

    What is the interest of a repository ? only for unit test ?

  • Joshua

    I have an error following this example : The type ‘Bussines.Client’ cannot be used as type parameter ‘T’ in the generic type or method ‘Bussines.IRepository’. There is no implicit reference conversion from ‘Bussines.Client’ to ‘Bussines.IEntity’. Can someone help me to fix this error?

  • Jalle

    you should fix your blog before writing such articles.
    you font size sucks colors are disaster and code blocks are soooo annoying