I am trying to set the connectionstring of my DbContext depending on each http request header. Is it possible to do so in .NET Core? I did it in MVC5 but I am not able to implement it in .NET core.
At
public void ConfigureServices(IServiceCollection services)
{
// ...
}
I don't know the http header, so where can I do it?
You should be able to do something like this to use the HTTP request content inside the DbContext
type instantiation:
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<HttpContext>(p => p.GetService<IHttpContextAccessor>()?.HttpContext);
services.AddDbContext<MyDbContext>();
var descriptor = new ServiceDescriptor(
typeof(DbContextOptions<MyDbContext>),
DbContextOptionsFactory,
ServiceLifetime.Scoped);
var descriptorNonGeneric = new ServiceDescriptor(
typeof(DbContextOptions),
typeof(DbContextOptions<MyDbContext>),
ServiceLifetime.Scoped);
services.Replace(descriptor);
services.Replace(descriptorNonGeneric);
// ...
}
private DbContextOptions<MyDbContext> DbContextOptionsFactory(IServiceProvider provider)
{
var httpContext = provider.GetService<HttpContext>();
// here we have the complete HttpContext
var myHeader = httpContext.Request.Headers["MyHeader"];
var connectionString = GetConnectionStringFromHeader(myHeader);
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionsBuilder.UseSqlServer(connectionString);
return optionsBuilder.Options;
}
Because the AddDbContext<TDbContext>
extension method of EFCore will already register a DbContextOptions
as a singleton, we need to overwrite this registration and add our own DbContextOption
factory method which uses HttpContext
and is executed with Scoped
lifetime.
This way we may change options (including the connection string) on every request.
This way you can do it even more streamlined
services.AddScoped<ISqlConnectionContext, SqlConnectionContext>();
services.AddDbContext<SqlDbContext>((sp, builder) =>
builder.UseSqlServer(sp.GetRequiredService<ISqlConnectionContext>().GetConnectionString()));
The SqlConnectionContext
can now be implemented in any way you want.
For example using the IHttpContextAccessor
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With