Design Patterns + Containerize .NET 6 API + Docker Networking

Barış Tutakli
DFDS Development Center Istanbul
5 min readJun 30, 2022

--

In the previous article, I made a quick introduction to Docker. Let’s move a step forward:)

This article consists of two parts. In the first part, I’m going to dig into the repository pattern, the generic repository pattern, and unit of works. In the second part, we will create one container for the database and one container for an API developed in the .NET6. Then we will use one of Docker networks to communicate API and the database. At the end of the article you can find the project link to clone the repository

Do not forget to read the comments in the code to understand better😜

Prerequisites

  • Visual Studio 2022
  • Docker
  • Curiosity😃
  • Patience😅

Repository Pattern & Generic Repository

The repository pattern is often used with ORM tools to handle the operations in the data access layer. When we use this pattern, we decrease the load in the application layer and separate concerns.

To better understand these patterns, let’s create a REST Web API. Consider that you want to create a blog project in .NET6. In the first step, you need to identify entities(models).

What entities do you need in this project?

You might need to create some of the following entities: Post, Category, Tag, Comment…

Let’s create two entities mentioned above and compare two cases(with and without repository pattern). Then, we’re going to implement generic repository pattern. You can see the entities below:

Post

Category

Assume that we want to get a post by a specific id, get all posts, add a new post, update a specific post and delete a specific post. Let’s start by creating an IPostRepository interface and an ICategoryRepository interface.

IPostRepository

ICategoryRepository

As we can not create an instance of interfaces, we need to implement these two interfaces. So, let’s create PostRepository and CategoryRepository classes.

Did you notice something in common between PostRepository and Category repository?

Yep, you are right!!! They look pretty much the same except for a few changes such as method parameters, return value types, etc.

How can we

  • avoid code repetitions?
  • type safety

As our entities are classes, we can restrict our generic repository with class and new() keywords that will restrict someone to put any type. Why not restrict the generic repository by a base type? Let’s restrict again our generic class using a base entity type that will be inherited by all the entities!

So, isn’t it better to create an abstract class that will derive our entities as below:

BaseEntity

Post.cs

Don’t forget to read the comments in the code:) Now we can create the generic class as below:

It’s time to refactor PostRepository and CategoryRepository😀 Here you can see that repositories are derived from GenericRepository class and act like their parents. As Post repository and Category repository inherit behaviors of parent class, we don’t need to write the same methods(GetById, GetAll…) again. If you want do override these methods, you should use virtual or abstract keywords depending on your aim. In addition, If you want to extend this PostRepository … , you can also use the Decorator Pattern.

Generic Repository

Let’s update PostRepository by inheriting generic repository.

In this project, I’m not going to add business logic because the article aims to create a REST API to explain repository pattern, generic repository pattern, unit of work, and docker and containerize an API. You can find the source code of the whole project via the link at the end of this article.

Now you saw how to implement the repository and generic repository pattern to your project. Let me show you two different ways of doing data access operations like create, update, delete… That will help you to understand the benefit of repository, generic repository pattern and unit of work. Then, you can decide one of them which suits best for you.

Injecting DbContext Into Controller

Do not forget to read the comments in the code😜

Injecting Post Repository Into Controller

Even though we don’t use DbContext in controller, there are still a lot of code which might be moved into a business or service class. You can create a service and move the business code into this service.

Unit of Work

In the previous scenario, you inject only PostRepository into Controller. If you needed to inject more repositories, would you inject them the same way you did for the PostRepository? If you prefer this, you will have a controller having a constructor as below:

Let’s Injecting Unit of Work Into Controller and see the difference. Isn’t your code cleaner than before?

Here are the IUnitOfWork interface and it’s implementation

x

Instead of injecting multiple dependencies into controller, we can inject only unit of work and use it as below:

  • _unitOFWork.Posts.Get() and _postRepository.Get() will do the same thing
  • _unitOFWork.Categories.Get() and _categoryRepository.Get() will do the same thing

Containerizing .Net Api and Mysql with Docker Compose

In the previous article, I made a quick introduction to Docker. You can read it also via the following link:

Dockerfile

Create a Dockerfile in the project folder and paste the code above.

Docker Compose

Creating containers isn’t enough for us because the API should connect to the database. What would happen If we run API and the database and send an HTTP request to the API?

Of course, the API can not get any data from the database. so, let’s communicate these containers with each other and make our clients happy😜

So, let’s create a docker-compose file. After running docker-compose file, we will see demo_demo_1 and demo_db_1 containers. The API is dependent on the database and will be connected to it via 1433 port.

Create a docker-compose file in the project folder and paste the code above. Let’s run the following commands in the directory where there is a Demo.csproj file.

Run the following command to create images:

docker-compose build

Run the following command to run containers

docker-compose run

Note: While creating the API, I chose the code first approach. So, we need to update the database that means we need to migrate any database changes on program. In the program.cs, the following code make migrations:

You can now test the program via Postman by making http requests and create a new post, get a specific post…

You can access and clone the project via the following link:

Would you like to help me to better my articles?🙂 Do let me know your view on this 🙂 See you next time!

--

--