EF Core inject dbcontext with many potential connection strings

asp.net-core c# entity-framework entity-framework-core


  • I have one master DB context that has a unique schema.
  • I have 100+ databases that have identical schema and exist on the same server.

A user authenticates against the master DB. After auth, depending on the user, the rest of the queries target a specific DB from my list of 100+ identical schema DBs.

In ASP .NET Core + EF Core, how do I register a factory or context that I can specify a connection string for post-injection (based on a provided value from the auth'd user)?

I'm playing with IDbContextFactory<MyDbContext> and a few other options, but I can't seem to find any clear examples of providing a connection string or connection property after the context has been injected.

5/26/2017 4:28:45 PM

Accepted Answer

Just create your own factory.

public interface ITentantDbContextFactory<T>
    T Create(string tenantId);

public class AppTenantDbContextFactory : ITenantDbContextFactory<AppDbContext>
    public AppDbContext Create(string tenantId) 
        // do some validations on tenantId to prevent users from 
        // injecting arbitrary strings into the connection string 
        var builder = new DbContextOptionsBuilder<AppDbContext>();

        // you can also load it from an injected option class

        return new AppDbContext(builder.Options);

Then inject the factory where ever you need it. Downside is that you have to manage the live time of the DbContext and dispose it.

You could also implement IDisposable interface on your factory and hold a list of references and dispose these when Dispose() method is called (which will be done at the end of the request, if your factory is registered as transient or scoped.

Also Unit of Work pattern comes helpful here, if you need to access more than one DbContext and use the tenantId (or whatever its called in your project) as key in a Dictionary<string, AppDbContext>, so you will get the same instance when calling factory.Create("tenantA"). Then add a SaveChanges method which will call SaveChanges of all instantiated AppDbContext instances

5/26/2017 5:15:52 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow