How to implement the Repository design pattern in C#

The Repository pattern implements separation of concerns by abstracting the data persistence logic in your applications

Repository pattern

Design patterns are used as a solution to recurring problems in your applications, and the Repository pattern is one of the most widely used design patterns. It will persist your objects sans the need of having to know how those objects would be actually persisted in the underlying database, i.e., without having to be bothered about how the data persistence happens underneath. The knowledge of this persistence, i.e., the persistence logic, is encapsulated inside the Repository.

In essence, the Repository design pattern facilitates de-coupling of the business logic and the data access layers in your application with the former not having to have any knowledge on how data persistence would actually take place.

In using the Repository design pattern, you can hide the details of how the data is eventually stored or retrieved to and from the data store. This data store can be a database, an xml file, etc. You can apply this design pattern to even hide how data that is exposed by a web service or an ORM is accessed. Martin Fowler states: "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects."

A Repository is defined as a collection of domain objects that reside in the memory. The MSDN states: "Use a Repository to separate the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model. The business logic should be agnostic to the type of data that comprises the data source layer. For example, the data source layer can be a database, a SharePoint list, or a Web service."

Implementing the Repository design pattern in C#

In this section we will explore on how we can program the Repository design pattern. In our implementation of the Repository design pattern, the participating types include the following:

  1. IRepository interface -- this interface is the base type for all Repository types
  2. Repository class -- this is the generic Repository class
  3. One or more Repository classes that implement the IRepository interface

Let's now dig into some code. The following class shows how you can define a base entity classes from which all your entity classes should be derived.

public abstract class EntityBase

   {

       public Int64 Id { get; protected set; }

   }

The class is defined as abstract with just one field -- named "Id". The "Id" field is common to all entities you generally use, isn't it? Here's how the generic IRepository interface would look like.

public interface IRepository<T> where T : EntityBase

   {

       T GetById(Int64 id);

       void Create(T entity);

       void Delete(T entity);

       void Update(T entity);

   }

The generic Repository class implements the IRepository interface and implements the members of the interface.

public class Repository<T> : IRepository<T> where T : EntityBase

   {

       public void Create(T entity)

       {

           //Write your logic here to persist the entity

       }

       public void Delete(T entity)

       {

           //Write your logic here to delete an entity

       }

       public T GetById(long id)

       {

           //Write your logic here to retrieve an entity by Id

           throw new NotImplementedException();

       }

       public void Update(T entity)

       {

           //Write your logic here to update an entity

       }

   }

Creating repositories for specific classes

If you would like to create a Repository for a specific entity, you should create a class that implements the generic IRepository<T> interface. The following code listing shows how this can be achieved.

public class CustomerRepository : IRepository<Customer>

   {

       //Write your code here to implement each of the methods of the IRepository interface.

   }

Similarly, if you were to create a ProductRepository, you should first create an entity class Product that extends the EntityBase class.

public class Product: EntityBase

   {

       public string ProductName { get; set; }

       public string Category { get; set; }

   }

The ProductRepository class should implement the generic IRepository<T> interface. Here's how the ProductRepository class would look like.

public class ProductRepository : IRepository<Product>

   {

       //Write your code here to implement each of the methods of the IRepository interface.

   }

Copyright © 2016 IDG Communications, Inc.

How to choose a low-code development platform