Hybrid-tenancy with MongoDB in .NET API — Part 02
By: Alex Alves
Tags: Code, Dotnet, Tenants, Architecture, Mongodb

Go to Part 01

For this article, we will focus on Hybrid-Tenant, according to the before part of this article. So, let’s see our scenario that we will build:

First, about the business rules: we will register many users in a different database, according to the register number of the company.

Second: all the data will store in MongoDB, so we will manipulate more than one database on it.

Third: we will build an API using .NET Core

Fourth and last: we will implement the tenancy technique in our project, according to request.

The complete solution will be:

So, after to create an instance of MongoDB (local or remote), and after to create the project in ASP.Net Core Web Application, of API type, let’s organize our structure:

The initial structure is like below:

First, let’s delete the WeatherForecast class and WeatherForecastController class. Next, let’s create 3 other folders:

Interfaces: location where stay the contracts of repositories. Used to make the Dependency Injection.

Database: location where stay the repository classes.

Middleware: location where stay the code that intercepts the requests and makes something.

Models: location where stay the model entities

The final structure will be like below:

Now, let’s code:

Model Entities

We need two specific entities, Customer and AppTenant. The customer entity will represent customer data:

And the AppTenant entity will contain the Register Number of Company:

Tenant Configuration

We need to install the package:

SaasKit.Multitenancy v1.1.4 (or latest)

We create a class in the Middleware folder:

It is necessary to inherit the ITenantResolver interface and implement it.

This class will receive the intercept the request, verify the headers, get the header that contains the register number of the company, and attribute it to AppTenant class.

To register this, we will need to input some codes in the Startup class.

Into the ConfigureServices, will be like below:

And into the Configure, will be like below:

Database configurations and operations

We need to install a package:

MongoDB.Driver v2.11.5 (or latest)

Before we starting, let’s define our connections parameters, in appSettings.json file:

Now, let’s configure our entities that will represent the register in the database, which will be the Customer entity, so we just go to update it:

We need too, of the class that will contain the operations methods to the database:

In the constructor, we will wait for the MongoClient, to do the operations, database name e collection name, by Dependency Injection.

We will inherit the ICustomerRepository, to implement it and to do the Inversion of Control

Finally, we need to configure the IMongoClient and the Repository, and we will do it in the Startup class:

In this case, we just build the connection string and create the MongoClient instance, like Singleton.

And this case, we recover the AppTenant data, to get the registration number of the company, to do a replacement on the database name, with the registration number. And finally, we will pass the MongoClient, database name formated and the collection name, to create the repository instance, like Transient.

The execution

We make the request below:

And in the cluster, will be crate a specific database, if it does not exist:

And, if I try to recover all data of a specific database. We will see all the data for only this company:

Conclusion

We can see that is very simple to make a solution for many clients, and we have more than one to do this. I would like to exalt this solution because I think this is more secure and simple to do. We can observe that we segregate the DBs but the business logic is the same.

The code you can look at GitHub.