[Architecture] — Creating a Singleton In-memory database in .NET

Tobi Adegunloye
3 min readDec 30, 2022

--

Oil Painting created using Stable Diffusion’s AI

To provide an easy starting point for stories in the future, I created this in-memory data store that can either be built from scratch or forked from Github. I implemented a thread-safe singleton design pattern from Refactoring Guru (Singleton (refactoring.guru)) to allow this to be used with asynchronous, multi-threaded applications with a rudimentary level of data integrity protection.

Our goal is to create a database capable of managing students and courses. We will develop this with SOLID principles and dependency inject our SingletonRepository at the end of the article. Here’s how we do this:

Folder Structure

We’ll start by defining a DataLayer folder where all our code will live, then create three folders in it. Like so:

Folder Structure

Models

Next, we’ll define our objects to be managed and stored by this singleton repository.

We’ll start with the Course repository. Add the course class to the Models folder and add the appropriate tests in a separate project.

Next, create the student class in the Models folder and add its tests in the StudentTests.cs file.

With our models created, we can start defining our interfaces.

Interfaces

We’ll start by defining an IObjectRepository<T> generic interface that defines a CRUD interface for an object T. Interfaces do not need to be tested and are generally boilerplate code:

Next, we’ll define two interfaces ICourseRepository and IStudentRepository that inherit from the IObjectRepository . Like so:

And then:

With our interfaces defined, we have to create our singleton repositories that implement these interfaces and implement the singleton pattern.

Repositories

Implementing the singleton repositories is the most complex and most well-tested aspect of our codeunit. To save time, I will embed the test classes for testing our repositories without explaining the test purpose. I’ll have to ask you, the reader, to trust me when I say that the tests verify each repository function and ensures that only one instance of our singleton can be created in multi-threaded environments.

We’ll stary by creating a CourseSingletonRepository.cs class that implements the ICourseRepository interface and add a private constructor (preventing the use of the ‘new‘ command). Next, we’ll create an initialization function called GetSingleton() that creates a single instance of our class during the lifetime of our application. Once we’ve verified that this code works, we’ll implement our repository CRUD methods and run tests on them. The code for the course repository is as follows:

The student singleton repository code is implemented similarly. However, we have a few more methods to be implemented from the IStudentRepository interface. It should look like this:

And the tests for those classes are as follows:

Conclusion

With this, we’ve got a functioning singleton repository that we can use in later projects! Happy coding!

Here is a repository containing the finished singleton repository and its classes: BelugaDiver/.NET-starting-point: Creates a thread-safe singleton in-memory database that manages students and courses. (github.com)

--

--

Tobi Adegunloye

Hi! I’m Tobi Adegunloye, a software engineer that loves cool tech stories!