The Repository Design Pattern in C#

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Design Patterns in C#

Design patterns are a solution to some of the recurring problems that occur in applications, and the Repository pattern is one of the most popular design patterns among them. It was introduced in 2004 initially as a part of the Domain-driven design pattern and is now one of the most recommended design patterns that can be integrated into an application that works with any kind of database.

What is the Repository Pattern in C#?

The Repository pattern is used for abstracting how data is persisted or retrieved from a database. The idea behind the Repository pattern is to decouple the data access layer from the business access layer of the application so that the operations (such as adding, updating, deleting, and selecting items from the collection) is done through straightforward methods without dealing with database concerns such as connections, commands, and so forth.

Before diving into the implementation of the Repository design pattern, let us first learn what a repository is. In brief, a repository can be defined as the collection of domain objects present in memory. According to the MSDN, “a repository is responsible for separating the logic of retrieving data and mapping it to the entity model from the business logic that acts on the model.” In simple terms, data comprising a data source layer – such as a database or a web service – should be agnostic from the business layer.

Read: Design Patterns: The Prototype Pattern

What are the Benefits of the Repository Pattern in C#?

As we have already discussed, the Repository pattern is the most widely used design pattern for working with any kind of database. So what makes it so good? Repository pattern is one of the preferred patterns to apply in an application because it allows programmers to integrate all of the fundamental data operations related to an entity in one main class. Without this pattern, developers would need to create multiple classes for each entity with the same logic.

Consider the following code example showing how to create a generic interface in C#:

public interface IRepository
{
TEntity FindById(params object[] values);
IEnumerable FindAll();
void Insert(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
} 

In the above interface, all the basic operations related to an entity are declared in the interface. Note that we have defined the interface for a generic entity, which means it can be used for any existing entity.

Read: .NET Design Patterns: The Builder Pattern

How to Implement Repository Design Patterns in C#

In this section, we will talk about how developers can program the Repository design pattern. When implementing the Repository design pattern, there are some types that participate in the process. They are listed below:
IRepository interface
Repository class
Repository classes that implement IRepository interface

Let’s get our hands dirty with the coding part. In the following section, you can see we have defined the base entity class EntityBase from which all the derived classes will be inherited:

public abstract class EntityBase {
    public int Id { get; set; }
}

The EntityBase class is defined as an abstract class with only one data field: Id. The Id field is generally common to all entities. Let’s now see how the generic IRepository interface look in C# code:

 
public interface IRepository where T : EntityBase
   {
       T GetById(int id);
       void Create(T entity);
 void Update(T entity);
       void Delete(T entity);
   }

Next, we will create the generic Repository class that implements the IRepository interface as shown here:

   public class Repository : IRepository where T : EntityBase
   {
       
       public T GetById(int id)
       {
           //Code to retrieve an entity by Id
           throw new NotImplementedException();
       }

       public void Create(T entity)
       {
           //Code to create the entity
       }

       public void Update(T entity)
       {
           //Code to update an entity
       }


       public void Delete(T entity)
       {
           //Code for deleting an entity
       }
       
   }

Read: .NET Design Patterns: The Abstract Factory Pattern

Creating Repositories for Specific Classes in C#

If you would like to create a Repository for a specific entity, then you need to create a class that implements the generic IRepository interface. The following code snippet shows how this can be achieved:

public class OrderRepository : IRepository
{
       // Implement each of the methods of the IRepository interface.
}

In the same way, if you want to create a CustomerRepository, you should first create an entity class Customer that inherits the EntityBase class:

   public class Customer: EntityBase
   {
       public string CustomerName { get; set; }
       public string CustomerAddress { get; set; }
   }

Then, the CustomerRepository class should implement the generic IRepository interface, which looks like the following:

public class CustomerRepository : IRepository
{
  // implement each of the methods of the IRepository interface.
}

Summary of C# Repository Design Patterns

The Repository design pattern allows programmers to maintain their code more effectively. The Repository pattern is a widely used pattern that can be integrated into an application no matter what kind of database it is operating on; it was introduced as a part of the Domain-Driven pattern. You can extend the functionalities of repositories by creating the extension classes for each repository.

Read: .NET Design Patterns: The Delegation Pattern

Tariq Siddiqui
Tariq Siddiqui
A graduate in MS Computer Applications and a Web Developer from India with diverse skills across multiple Web development technologies. Enjoys writing about any tech topic, including programming, algorithms and cloud computing. Traveling and playing video games are the hobbies that interest me most.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read