Generic Repository Pattern in C#

It’s a good practice to separate data access layer from business logic. Tight coupling of the database logic in the business logic make applications difficult 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
  4. Difficulty to change the database provider (EntityFramework can be a solution).

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 Framework. In the future, underlying data sources or architecture can be changed without affecting the business logic.

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

Let’s consider the base IEntityBase.cs for each entity in the database.

Generic Repository Interface of the type IEntityBase can be created as follows. I have added 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 Employee table. To represent this, we have created an entity class Employee. Employee entity class should extend the IEntityBase class to work with the generic repository.

To create EmployeeRepository, create a class that will implement the generic repository interface IRepository<Employee>. I am performing CRUD operations using the Entity Framework. However, you may use any option like LINQ to SQL, ADO.NET etc.

The implemented generic repository can be used as follows:


Singleton with System.Lazy

A Singleton class is one where there is only ever one instance of the class created. This means that constructors must be private to avoid users creating their own instances, and a static property (or method in languages without properties) is defined that returns a single static instance.

This is the most basic singleton, notice the key features:

  1. Static readonly field that contains the one and only instance.
  2. Constructor is private so it can only be called by the class itself.
  3. Static property that returns the single instance.

Looks like it satisfies, right? There’s just one (potential) problem. C# gives you no guarantee of when the static field _instance will be created. This is because the C# standard simply states that classes (which are marked in the IL as BeforeFieldInit) can have their static fields initialized any time before the field is accessed. This means that they may be initialized on first use, they may be initialized at some other time before, you can’t be sure when.

So what if you want to guarantee your instance is truly lazy. That is, that it is only created on first call to Instance?

First option is to use lazy construction ourselves, but being that our Singleton may be accessed by many different threads, we’d need to lock it down.

This is a standard double-check algorithm so that you don’t lock if the instance has already been created. However, because it’s possible two threads can go through the first if at the same time the first time back in, you need to check again after the lock is acquired to avoid creating two instances.

Second option is to take advantage of the C# standard’s BeforeFieldInit and define your class with a static constructor. It need not have a body, just the presence of the static constructor will remove the BeforeFieldInit attribute on the class and guarantee that no fields are initialized until the first static field, property, or method is called.

Third option is to use .Net 4.0 new features, System.Lazy type which guarantees thread-safe lazy-construction. Using System.Lazy, we get:

Note, you need your lambda to call the private constructor as Lazy’s default constructor can only call public constructors of the type passed in (which we can’t have by definition of a Singleton). But, because the lambda is defined inside our type, it has access to the private members so it’s perfect.

Lazy has many other uses as well, obviously, but I really love how elegant and readable it makes the lazy Singleton.

The S.O.L.I.D. Principles

The S.O.L.I.D. design principles are a collection of best practices for object-oriented design. All of the Gang of Four design patterns adhere to these principles in one form or another. The term S.O.L.I.D. comes from the initial letter of each of the five principles that were collected in the book Agile Principles, Patterns, and Practices in C# by Robert C. Martin, or Uncle Bob to his friends.

1. Single Responsibility Principle (SRP)
The principle of SRP is closely aligned with SOC (Separation of Concerns). It states that every object should only have one
reason to change and a single focus of responsibility. By adhering to this principle, you avoid the problem of monolithic class design that is the software equivalent of a Swiss army knife. By having concise objects, you again increase the readability and maintenance of a system.

2. Open-Closed Principle (OCP)
The OCP states that classes should be open for extension and closed for modification, in that you should be able to add new features and extend a class without changing its internal behavior. The principle strives to avoid breaking the existing class and other classes that depend on it, which would create a ripple effect of bugs and errors throughout your application.

3. Liskov Substitution Principle (LSP)
The LSP dictates that you should be able to use any derived class in place of a parent class and have it behave in the same manner without modification. This principle is in line with OCP in that it ensures that a derived class does not affect the behavior of a parent class, or, put another way, derived classes must be substitutable for their base classes.

4. Interface Segregation Principle (ISP)
The ISP is all about splitting the methods of a contract into groups of responsibility and assigning interfaces to these groups to prevent a client from needing to implement one large interface and a host of methods that they do not use. The purpose behind this is so that classes wanting to use the same interfaces only need to implement a specific set of methods as opposed to a monolithic interface of methods.

5. Dependency Inversion Principle (DIP)
The DIP is all about isolating your classes from concrete implementations and having them depend on abstract classes or interfaces. It promotes the mantra of coding to an interface rather than an implementation, which increases flexibility within a system by ensuring you are not tightly coupled to one implementation.

using Statement

The C# ECMA specification states that a using statement:

is exactly equivalent to:

This relies on the IDisposable interface from the System namespace:

Note that the cast inside the finally block implies that variable must be of a type that supports the IDisposable interface (either via inheritance or conversion operator). If it doesn’t you’ll get a compile time error.

Using on classes without IDisposable

It’s instructive to consider what would happen if class didn’t implement the IDisposable interface and you must implement Disposability in our own classes. One solution is the Object Adapter pattern. For example:

which you would use like this:

To make things a little easier you can create an implicit conversion operator:

which would allow you to write this: