问题
I have an ASP.NET Core application using the DI from Microsoft.Extensions.DependencyInjection
. The app connects to a stupid number of databases with an exact same interface, let's say a 100 of them. I want to facade them all with the same DbContext, say ExternalDbContext
. The only difference between them is the connection string they're using. I need to instantiate the correct version of the context for a given request. So the chain of resolution would go like this:
- User makes a request that has a
provider = 'ABCD'
parameter. - This is mapped to an Action in a Controller which has an
ISomeService
as a dependency. - That service has a method
DoStuff(string provider)
. - Here's the crucial part. The
ISomeService
needs a dependency on the data layer, but this cannot be a hard dependency on one injectedExternalDbContext
, since that has to be resolved dynamically. My idea is to have anIExternalDbContextFactory
which in turn can take anIServiceProvider
. That factory would have a methodGetExternalDbContext(string provider)
and I would resolve the correctExternalDbContext
using the injected service provider.
To achieve that I would have to register the ExternalDbContexts
in a way that would allow me to resolve them from an IServiceProvider
based on a string parameter. For obvious reasons I don't want to have a 100 different useless marker classes inheriting from ExternalDbContext
and then register them independently. Also I would prefer to use the handy AddDbContext
method somehow.
I obviously could build my own resolution infrastructure entirely, but I'd rather reuse an existing solution than spend days writing and testing boilerplate for this particular use case.
回答1:
You can manage connection strings using overload of AddDbContext
which provides you access to IServiceProvider:
public void ConfigureServices(IServiceCollection services)
{
services
.AddEntityFrameworkSqlServer()
.AddDbContext<ExternalDbContext>((serviceProvider, options) =>
{
var connectionString = serviceProvider.GetService // get service
// which can determine connection string
.GetConnectionString();
options.UseSqlServer(connectionString);
});
}
}
For example you can resolve IHttpContextAccessor
there and check the request parameter.
来源:https://stackoverflow.com/questions/62412065/net-core-dependency-injection-many-databases-one-dbcontext