Building a Generic Repository

NOTE: This post is part of a series of posts for defining a repository. Please follow the table of contents for other related posts.

Table Of Contents

  1. Setting up the Solution

Setting up the Solution

Hi, it has been loooooooooooong since my last post. I am going to start a new series of articles and today is the first – to build a generic repository that can work with any kind of domain as oppose to individual repository per domain. Lets build the repository.

  1. I usually start with a blank solution, lets name it Atl.GenericRepostitory.
  2. Add 2 projects
    1. A Class library project to containing the repository. Lets name it Atl.Repository.
    2. A unit test project name Atl.Repository.Test.
  3. I am going to use xUnit for unit testing. So lets install them right away.  Fire up nuget package manager console and install the following 2 packages, one for xUnit and the other to enable running xUnit test cases from visual studio –
    PM> install-package xunit
    PM> install-package xunit.runner.visualstudio
  4. At the end you will end up with a solution with two projects and one of them is setup to run xunit tests –
    1

Defining the Interfaces for the Repository

Now, let us start the interesting part.

Before we begin defining our interfaces, we need to make sure our definition of repository contains all the basic functionality needed and in addition supports the following things –

  1.  The repository should be able to support any UML Patterns used to design the business layer that communicates with the Repository and thus be able to handle Read/Write commands sequentially or non-sequentially. One particular example of this scenario is that the repository could be used in a Service Layer Pattern and at the same time some other code base might use CQRS pattern.
  2. While writing to a repository required atomic action, reading from a repository does not necessarily need that. Thus we can increase system performance significantly by separating ReadOnly and WriteOnly repository.
  3. To be able to create ReadOnly and WriteOnly repositories we need to be able to separate responsibilities of a whole Repository in 3 groups –
    1. Responsibilities while reading contents
    2. Responsibilities while writing/saving/updating contents
    3. Responsibilities while deleting contents

Keeping all these in mind we can come up with the following structure and inheritance of interfaces for the repository.

  1. The root is the IRepository, the generic template parameter for this is IDomain. A signature of the actual domain as of now and later we will add more properties to the IDomain object.
  2. The generic implemenation of IRepository is going to be IGenericRepository where T: IDomain.
  3. Three Individual interfaces inheriting GenericRepository to provide robust implementation but yet clustering codes into different familiar groups. For now, we will go with 3 interfaces –
    1. IWriteRepository
    2. IReadRepository
    3. IDeleteRepository

the interface definition of the repository will look like this –

IRepository

public interface IRepository { }

IGenericRepository    

 
 
public interface IGenericRepository<T> : IRepository where T: IDomain { }

And the other three repositories –

 public interface IReadRepository<T> : IGenericRepository<T> where T : IDomain
  {
     T GetById(int id);
     IEnumerable GetAll<T>();
  }
 
  public interface IWriteRepository<T> : IGenericRepository<T> where T : IDomain
  {
     T Add(T obj);
     T Update(T obj);
  }
 
  public interface IDeleteRepository<T> : IGenericRepository<T> where T : IDomain
  {
     //the deletion method
     void Delete(int id);
     void Delete(T obj);
  }
}

Now lets define the concrete class Repository –

public partial class Repository<T> : IGenericRepository<T> where T : IDomain
{
    private readonly DbContext _dbContext;

    public Repository()
    {

    }

    public Repository(DbContext context)
    {
        _dbContext = context;
    }
}
 
 public partial class Repository<T> : IReadRepository<T> where T: IDomain
 {
     public T GetById(int id)
     {
         throw new NotImplementedException();
     }
 
     public IEnumerable<T> GetAll()
     {
         throw new NotImplementedException();
     }
 }
 public partial class Repository<T> : IWriteRepository<T> where T : IDomain
 {
     public T Add(T obj)
     {
         throw new NotImplementedException();
     }
 
     public T Update(T obj)
     {
         throw new NotImplementedException();
     }
 }
public partial class Repository<T> : IDeleteRepository<T> where T : IDomain
{
    public void Delete(int id)
    {
        throw new NotImplementedException();
    }

    public void Delete(T obj)
    {
        throw new NotImplementedException();
    }
}

The reason for using partial classes for individual repository types is to take advantage of organizing the repository methods separately, otherwise the repository will look like a mammoth. Each of the methods defined will have much more siblings coming along.

At this point your solution should look like this –

2.PNG

Note: Please ignore DatabaseContext/IDatabaseContext, we will talk about it later.

Next Post: Let’s set up the test project

Advertisements

About Mahmudul Islam

Senior Software Engineer Sitback Solutions (https://www.sitback.com.au/)
This entry was posted in ADO.Net Entity Framework, C# .Net and tagged , , , , . Bookmark the permalink.

One Response to Building a Generic Repository

  1. Pingback: Building a Generic Repository using Repository Pattern – Heart of a Brainless Coder

I would like to say something ...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s