si2030
si2030

Reputation: 4035

DotNet Core setting the connection string after startup has run

I have a Visual Studio solution that has two database connections. The first is a catalog holding username password and database. The second will be the users data. I can set up the connection for the catalog database in "ConfigureServices" and thats fine. Once the user has attempted to log in and succeeded I can then know the database the user will connect to.

My problem is, How do I create the service after startup has run.. how do I use the connection string to add a DBcontext in the normal course of operations. From my searches this is OK if you know the connection string at start up..

var connection = @"Server=(localdb)\mssqllocaldb;Database=JobsLedgerDB;Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<BloggingContext>(options => options.UseSqlServer(connection));

But if I dont have a connection string at startup... How do I add a service after the project is already up and running when I finally do have the connection string?

Upvotes: 4

Views: 2397

Answers (2)

Peter Bons
Peter Bons

Reputation: 29770

The other answer by Tolbxela suggest creating a new context when needed, where needed but that does not work if you want to use dependency injection. Instead, you should provide a factory like this in the ConfigureServices method of your Startup class using the AddDbContext extensions method as Camilo stated in the comment of that answer:

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        ...

        services.AddDbContext<BloggingContext>(options =>
        {
            var customerId = serviceProvider.GetService<IHttpContextAccessor>().HttpContext?.User?.FindFirst("customerId")?.Value;
            var connectionString = 
                $"bla blah blah ;Initial Catalog={customerId}";
            options.UseSqlServer(connectionString);

In this example the initial catalog is set to the value of a claim "customerId". (FindFirst is a custom extension method I wrote myself). This example is only to give you an idea of the approach.

You can then inject your context like you would normally do:

public class MyController : Controller
{

    public MyController(BloggingContext context)
    {
        ...
    }
};

Upvotes: 2

Tolbxela
Tolbxela

Reputation: 5183

You can instantiate your DbContext in every class of your application.

Check the docs: Configuring a DbContext

Example

var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Data Source=blog.db");

using (var context = new BloggingContext(optionsBuilder.Options))
{
  // do stuff
}

For your SQL Connection

var connection = @"Server=(localdb)\mssqllocaldb;Database=JobsLedgerDB;Trusted_Connection=True;ConnectRetryCount=0";
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlServer(connection);

using (var context = new BloggingContext(optionsBuilder.Options))
{
  // do stuff
}

Upvotes: 0

Related Questions