Eugene Sukh
Eugene Sukh

Reputation: 2727

Get connection string from application.json

I have .Infrastructure project for Entities and migrations and .Web project with application.json file, where I have connection string

In Infrastrusture project I have ApplicationContextFactory to run migrations

Here is code

public class ApplicationContextFactory: IDesignTimeDbContextFactory<ApplicationDbContext>
{
    public ApplicationDbContext CreateDbContext(string[] args)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
        var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        optionsBuilder.UseSqlServer(connectionString);
        return new ApplicationDbContext(optionsBuilder.Options);
    }
}

This string is not working, because application,json file is in .Web project.

.SetBasePath(Directory.GetCurrentDirectory())

Here is my solution structure

enter image description here

How I can get connection string from it?

Upvotes: 0

Views: 554

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239440

Specifically, IDesignTimeDbContextFactory is for migrating against something like a class library, where there's not a startup project involved. If you are fine with using an explicit startup project when migrating, then see @poke's answer, and get rid of your factory, as you don't need it.

However, if you want to keep going this route, you should realize that as its name indicates, this is for "design time", i.e. development. As such, getting a connection string from configuration doesn't really make sense, as it's always going to be your development database. That's why the docs just reference this connection string explicitly. Not sure why every developer seems to think they need to second-guess Microsoft on this.

It shouldn't even really pose an issue in a team environment. If you use the local MSSQLLocalDb instance, and all your devs are using Visual Studio, then the connection string is effectively developer agnostic. Or, if you spin up a SQL Server instance in a container, then every developer will be working off that same container setup.

If there is some scenario where you need to allow developer-specific connection strings, then you can use configuration for that. However, you should then just be hitting User Secrets, and you still don't need access to appsettings.json in your web project.

Upvotes: 2

poke
poke

Reputation: 388303

In order to run migrations for a library project but use the configured connection string from a different project, you will need to specify the startup project as you run migrations commands.

For example, to add a migration:

cd src\TooSeeWeb.Infrastructure
dotnet ef migrations add ExampleMigration -s ..\TooSeeWeb

This will specify ..\TooSeeWeb as the startup project, so the migration will run as if everything EF related was actually inside that web project.

Similarly, that -s or --startup-project parameter can also be used with other commands, e.g. dotnet ef database update -s ..\TooSeeWeb.

Upvotes: 1

Related Questions