DotNetCore

Generic Repository Pattern: .net core

A typical software application will invariably need to access some kind of data store to in order to carry typical CRUD (Create, Read Update, Delete) operations on data. This could be some kind of database, file system or any kind of storage mechanism used to store data.

In some cases saving or creating data may actually require persistence to new files in others it may be creating a new row in a data table. In other cases when saving new data it may actually require a number of interactions with several web-based services.

In most modern software applications it is becoming increasingly common for the application to have several different data stores from different vendors or even different application Apis. For instance, you may be accessing data from an Oracle HR database, accounting data may be in a SQL server, customer data may be in mySQL based CRM and Product data may be stored in a Cloud Hosted Inventory Management Database.

Your application may be required to perform modifications to all these systems during a course of a transaction. In most cases, you may also have several different data access strategies such as any number of different Object Relational Mappers (ORM) to interact with the various databases.

The challenge for developers in these types of scenarios, is often they don’t want to expose the varying different data access logic to their UI or even Business Logic Layers often with the aim of abstracting it in order to reduce direct dependencies.

It is in cases like this that the Repository Pattern comes in extremely useful.

The repository pattern is discussed extensively in the following resources Patterns of Enterprise Application Architecture (The Addison-Wesley Signature Series) and Domain-Driven Design: Tackling Complexity in the Heart of Software .

The two books are an essential component of any developers reference materials. I feel the two books work well together in providing Enterprise software developers a thorough grounding on the importance of software patterns and how and when to consider and use them when designing and developing software applications.

Patterns of Enterprise Application Architecture is basically two books in one. The first is a short tutorial on developing enterprise applications, which you can read from start to finish to understand the scope of the book’s lessons.

The second part of the book provides a detailed reference to software design patterns themselves. Each pattern provides usage and implementation information, as well as detailed code examples in Java or C#. The entire book is also richly illustrated with UML diagrams to further explain the concepts.

Domain-Driven Design provides a systematic approach to domain-driven design, presenting an extensive set of design best practices, experience-based techniques, and fundamental principles that facilitate the development of software projects facing complex domains.



What is the Repository Pattern

Software developers use the repository pattern to separate the logic that retrieves the data and maps it to an entity model from the business logic that acts on the model. This enables the business logic to be agnostic to the type of data that comprises the data source layer.

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.

 

I’ve been using a Generic Repository Pattern in some form or fashion for a number of years. The Repository Pattern is by far the approach to abstract away the details of the data access layer from the rest of the application. Using a Generic Repository is much easier to keep from business logic creeping in where it doesn’t belong!

The repository acts as a mediator between the data source layer and the business layers of the application. It queries the data source for the data, maps the data from the data source to a business entity, and persists changes in the business entity to the data source.

The Repository Pattern separates the business logic from the interactions with the underlying data source, irrespective of the data source type.

Benefits of the Repository Pattern

  • Centralization of the data access logic.
  • Substitution point for the unit tests.
  • Flexible architecture that can be adapted as the overall design of the application evolves.

 

In order to enable your application to meet all the illities i.e.

  • Scalability
  • Adaptability
  • Testability
  • Usability
  • Maintainability
  • Reliability
  • Extensibility
  • Portability
  • Interoperability
  • Compatability
  • Reusability

It’s important to break up the development of your application into layers.  Each layer can then be injected.

This provides levels of abstractions for your various layers in that they do not necessarily explicitly care where the data from each layer is persisted and retrieved from only that it conforms to an explicit data contract.

RepositoryPattern

This also enables ease of testing by providing the ability to inject Mock or Fake abstracted classes to provide data.



Unit Of Work

When implementing a Repository pattern it is also important to understand the Unit of Work pattern. Fowler provides an explanation of the Unit Of Work pattern

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you’re done, it figures out everything that needs to be done to alter the database as a result of your work.

The unit of work represents a transaction when used in data layers. Typically the unit of work will roll back the transaction if Commit() has not been invoked before being disposed.

Can’t wait to see it in action ?

Check out the code on GitHub

Code

How to implement the repository pattern

In this example we are going to implement a very simple repository pattern based solely on making use Entity Framework core. This serves to highlight the constituent parts of the repository pattern. In later articles we will build on this sample and develop a slightly more complex repository with built in Domain Object to Entity mapping and ORM agnostic integration.

The repository pattern is really easy to implement, but it is also incredibly easy to over complicate it. When starting out with the repository pattern, it is best to stick to the principles of YAGNI (You ain’t Gonna Need It), with this in mind always try to keep your repository simple and clean.

Why use the Repository Pattern to Wrap a Repository

This is a valid question!

Taking a high-level view of an ORM, such as Entity Framework (EF) , one might conclude that it is nothing more than an implementation of the Repository Pattern. It is, and it does provide an abstraction for interacting with the database. Almost eliminating the need for developers to write SQL queries directly in their code and providing the ability to design and manage the database.

Undoubtedly there will be POCO classes define that reflect the Database entities etc. However, in many cases, these may not always resemble the Business Model of the entities. You may have Domain Entity models which, may actually comprise several Database Entities into one Model.

The issue here is that you end up exposing your Database Object Model to your Middle and even User Interface, which can lead to some crazy misunderstanding and confusion.

Obviously, this is also dependent on the size and purpose of your application, but in most large-scale applications you may want to provide another level of abstraction to make it easier to manage your data layer.

Generally, it is a good idea to expose your Repository layer to a Service layer, which then provides domain entity objects to the UI & Business Layer.

Another use case may be, that EF actually has a lot of functionality that you may not want to be exposed to your application. So developing a Repository abstraction layer provides a means for controlling what functionality is available.

For instance, in the example, we may want to exclude Asynchronous Functionality to our database. Which is still a valid use case. So we will create a repository abstraction layer that only provides synchronous methods to interact with data.

Repository Interface

We will start off developing our Repository by defining an interface it is going to adhere too.

The interface defined here is a simple one with just a handful of methods in order to sufficiently describe and implement the repository pattern.

I would caution the reader that, this is not a full implementation, but rather an example. It serves to highlight to the type of functions that are implemented in a repository pattern.

View Code
We will also define a Simple Unit Of Work interface.

View Code
The code we will implement for our Unit Of Work is just enough to get it working at this stage. Due to the fact we are going to following a Test Driven Development (TDD) approach to our development work. We will enhance and improve the functionality of the unit of work as required as we progress down the development path.

View Code

Repository

We can simply define our base repository class add the logic to the method it will need to perform. We have also kept the code very simplistic and implemented just enough code to get it working

View Code

You will notice from the example above, we have injected the IUnitOfWork into the Repository class. You may also notice that there aren’t any transactions implemented within the repository class, that’s because transactions need to be implemented at a higher level because a transaction may contain several operations across different repositories.

The Unit of WOrk is the area of code in which you may attempt to set the scope that the same IUnitOfWork instance will be used everywhere within a single request. Having a single Unit or Work per request is necessary for the pattern to function correctly.

In theory, you should inject your Unit of work into your repository classes. However, in practice you may have need to deviate.

In this example, the Unit of Work is also used to provide access to the Database Context that is shared across all Repositories.

Conclusion

We have now completed most of the code implementation of our Generic Repository Pattern for .net core Entity framework. In the next post, we will take a look at integrating it with an Entity Framework class library and make use of it in a service layer.

The Repository pattern is intended to create an abstraction layer between Data Access layer and business layer so it can help to insulate the application from changes in the data store and facilitate automated unit testing for test-driven development.

Gary Woodfine

Freelance Full Stack Developer at threenine.co.uk
Helps businesses by improving their technical proficiencies and eliminating waste from the software development pipelines.

A unique background as business owner, marketing, software development and business development ensures that he can offer the optimum business consultancy services across a wide spectrum of business challenges.
π