I'm developing a Web API application with ASP.NET Core 5 with the goal of being multitenant capable. Each tenant will have their own database.
In this application I will have two DbContext:
DBContextMaster- this context data will be static inappsettings.json. It will get the information of the tenant making the request from the Web API and get the name of the database stored for that specific customerDBContextTenant- this context will have a connection string inappsettingssimilar to this:"DynamicTenant": "Data Source=server;Initial Catalog={dbName};Integrated Security=False.{dbName}must be replaced in order for the correct database to be used.
I have some questions about how to do this, but my idea would be:
- send the tenant code or a kind of APIKEY with the request
- validate if the tenant exists and then replace the
DynamicTenantconnection string (deploy some kind of cache to avoid successive queries checking if the same tenant exists)
As I am just starting with ASP.NET Core, I would like to know how and where I could dynamically load the tenant context.
UPDATE:
This code will apparently serve me well.
services.AddDbContext<DbContextTenant>((serviceProvider, dbContextBuilder) =>
{
var connectionStringPlaceHolder = Configuration.GetConnectionString("DynamicTenant");
var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
var dbName = httpContextAccessor.HttpContext.Request.Headers["tenantId"].First();
var connectionString = connectionStringPlaceHolder.Replace("{dbName}", dbName);
dbContextBuilder.UseSqlServer(connectionString);
});
But now I have another problem. When running the project there is no error, but when trying to add a new controller using this dbcontext, the following error occurs "Object reference not set to an instance of an object". Same error when I try to enable Migrations for the project.
I assume the error is occurring because at development time there is no http context.
What implementation can be done to get around these problems?