Cached Repository Pattern in C#

In this article, we will learn about Caching a Repository Pattern in C# and .NET 8 and we call this Cached Repository Pattern.

If you are new to design patterns then please read this – Design Pattern in C#

Download the source code for this article : SharePointCafe GitHub Repository

What is a Cached Repository Pattern?

It is a Repository Pattern with caching which makes the application super fast. We will implement a cached repository pattern without any changes to our existing repository pattern.

In other words, this is a combination of the Repository Pattern and Cache mechanism to enhance the application performance.

Cached Repository Pattern with C# and .NET 8

To demonstrate this pattern we need the following:

  • Visual Studio 2022
  • .NET 8 Framework
  • C# 12

Firstly, we will see the application behaviour and architecture without caching.

We have an interface i.e. IHomeRepository

public interface IHomeRepository
{
    public Task<List<Content>> GetHomePageContent();
}

Here, we have only one method GetHomePageContent()

Next, we will implement this interface. So, we have a class HomeRepository

public class HomeRepository : IHomeRepository
{
    private AppDBContext _dbContext;

    public HomeRepository(AppDBContext appDBContext)
    {
        _dbContext = appDBContext;
    }

    public async Task<List<Content>> GetHomePageContent()
    {
        var data = await _dbContext.Content.ToListAsync();
        return data;
    }
}

The class has a constructor which initializes the AppDBContext file and implements the interface.

So, in this way, we implement the Repository pattern. But, what is the issue?

To be frank, there is no logical issue.

The only point is if there is no change in database records, still we hit the database every time the browser sends the request.

So, what is the solution? Do we need to change our code?

No, not at a bigger level.

We will apply a caching layer, and if data is available in cache memory then it will return from there only otherwise, it will access the existing repository method to access the database.

Let’s see this in action.

Implement Cache Repository Pattern

To do this, let’s create a class CachedHomeRepository.

Inherit this class with IHomeRepository and apply caching behaviour to this.

So, here we are applying the caching mechanism and that too without modifying the existing repository class.

Let’ see this class:

public class CachedHomeRepository : IHomeRepository
{
    private readonly HomeRepository _homeRepository;
    private readonly IMemoryCache _memoryCache;
    private MemoryCacheEntryOptions cacheOptions;

    public CachedHomeRepository(HomeRepository homeRepository, 
                                               IMemoryCache memoryCache)
    {
        _homeRepository= homeRepository;
        _memoryCache = memoryCache;
        cacheOptions = new MemoryCacheEntryOptions()
        .SetAbsoluteExpiration(TimeSpan.FromMinutes(20));
    }

    public Task<List<Content>> GetHomePageContent()
    {
        string cacheKey = "homepage";
        return _memoryCache.GetOrCreateAsync(
            cacheKey,
            entry =>
            {
                entry.SetOptions(cacheOptions);
                return _homeRepository.GetHomePageContent();
            });
    }
}

In this class, we use IMemoryCache available in the ASP.NET Core. Then we inject the memory cache using the constructor of the class.

Finally, we use the GetOrCreateAsync() method of CacheExtension class to check if the data is available in cache memory or not. Otherwise, call the actual method of the repository pattern.

This is to note that, we have not modified the existing code till now.

Now, we register the service in the Program.cs file:

builder.Services.AddTransient<HomeRepository>();
builder.Services.AddTransient<IHomeRepository, CachedHomeRepository>();

Benefits of Cached Repository Pattern

There are multiple reasons we should use caching with Repository Pattern. Some of the benefits are :

  • Improved Performance
  • Reduced Database load
  • Avoid unnecessary network traffic

From a coding perspective, the major benefit is that we do not require major code changes to implement this in the existing C# .NET Core application.

Conclusion

In the article, we just learnt the Cached Repository Pattern with C# and .NET Core. The idea behind the example is to explain how we can implement the Repository pattern by putting the data in a cache memory to make a high-performance application.
I hope this article is useful to you.

Leave a Comment

RSS
YouTube
YouTube
Instagram