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

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.

public class IEntity
{
public string Id;
}

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.

public interface IRepository<T> where T: IEntity
{

IEnumerable<T> List { get; }
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T FindById(int Id);

}

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.

[Table("Author")]
public partial class Author : IEntity
{
public int Id { get; set; }

[Required]
public string authorname { get; set; }
}

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:

public class AuthorRepository : IRepository<Author>
{

Model1 _authorContext;

public AuthorRepository()
{
_authorContext = new Model1();

}
public IEnumerable<Author> List
{
get
{
return _authorContext.Authors;
}

}

public void Add(Author entity)
{
_authorContext.Authors.Add(entity);
_authorContext.SaveChanges();
}

public void Delete(Author entity)
{
_authorContext.Authors.Remove(entity);
_authorContext.SaveChanges();
}

public void Update(Author entity)
{
_authorContext.Entry(entity).State = System.Data.Entity.EntityState.Modified;
_authorContext.SaveChanges();

}

public Author FindById(int Id)
{
var result = (from r in _authorContext.Authors where r.Id == Id select r).FirstOrDefault();
return result;
}

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:

IRepository<Author> repository = new AuthorRepository();
var result = repository.List;
foreach (var r in result)
{
Console.WriteLine(r.authorname);

}

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!


Originally published at Falafel Software Blog.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.