简体   繁体   中英

.NET Core dependency injection - many databases, one DbContext

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:

  1. User makes a request that has a provider = 'ABCD' parameter.
  2. This is mapped to an Action in a Controller which has an ISomeService as a dependency.
  3. That service has a method DoStuff(string provider) .
  4. Here's the crucial part. The ISomeService needs a dependency on the data layer, but this cannot be a hard dependency on one injected ExternalDbContext , since that has to be resolved dynamically. My idea is to have an IExternalDbContextFactory which in turn can take an IServiceProvider . That factory would have a method GetExternalDbContext(string provider) and I would resolve the correct ExternalDbContext 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM