Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

User secrets getting loaded at runtime but not at design time

I’m using IHost to create a service provider in a console app. I have set up user secrets that get loaded when running the project. However when I use the Package Manager Console with commands like Add-Migration user secrets don’t get loaded.

public static async Task Main()
{
    IHost host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, serviceCollection) =>
        {
            serviceCollection
                .AddDbContext<ApplicationDbContext>();
        })
        .Build();

    // Other code
}
public class ApplicationDbContext(IConfiguration configuration) : DbContext
{
    public DbSet<TestRequest> TestRequests { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // This foreach loop doesn't log anything stored in user secrets at design-time while it does at runtime
        foreach (var item in configuration.AsEnumerable())
        {
            Console.WriteLine(item);
        }

        string connStr = configuration.GetConnectionString("MySql") ??
            throw new NullReferenceException("MySQL conncetion string was null"); // Throws at design time

        optionsBuilder
            .UseMySql(connStr, ServerVersion.AutoDetect(connStr));
    }
}

My user secrets ID is set in the .csproj file.

secrets.json

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
    "ConnectionStrings:MySql": "Server=localhost;Database=db;Uid=root;Pwd=mypwd;"
}

>Solution :

This issue occurs because configuration data (especially user secrets) isn’t loaded at design-time. When you run your application, Host.CreateDefaultBuilder() loads the configuration and user secrets, but when running commands like Add-Migration, this doesn’t happen.

To fix this, you can create a class that implements the IDesignTimeDbContextFactory<T> interface. This class tells Entity Framework how to create your DbContext at design time.

Here’s how you can do it:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;

public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
    public ApplicationDbContext CreateDbContext(string[] args)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json") // If needed
            .AddUserSecrets<ApplicationDbContextFactory>()
            .Build();

        var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();

        string connStr = configuration.GetConnectionString("MySql") ??
            throw new NullReferenceException("MySQL connection string was null");

        optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));

        return new ApplicationDbContext(configuration, optionsBuilder.Options);
    }
}

Then, update your ApplicationDbContext class like this:

public class ApplicationDbContext : DbContext
{
    private readonly IConfiguration _configuration;

    public ApplicationDbContext(IConfiguration configuration, DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
        _configuration = configuration;
    }

    public DbSet<TestRequest> TestRequests { get; set; }

    // You can remove the OnConfiguring method if you don't need it anymore
}

By doing this, the configuration and user secrets will be loaded at design-time as well, so the Add-Migration command will find the connection string.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading