Display Name
Display Name

Reputation: 15101

How to get IConfiguration from within Main?

The following is just for illustration purpose.

I have a secrets.json with the following contents:

{   
  "Message": "I still know what you did last summer."
}

And I need to seed the database with the following seeder.

public static class SeedData
{
    public static void Initialize(IServiceProvider isp, IConfiguration c)
    {
        using (var context = isp.GetRequiredService<MyContext>())
        {
            if (context.Members.Any())
                return;

            context.Members.AddRange
            (
                new Member
                {
                    Message= c["Message"]
                }
            );

            context.SaveChanges();
        }
    }
}

The seeder is invoked inside Main as follows.

public static void Main(string[] args)
{
    IWebHost iwh = BuildWebHost(args);

    using (IServiceScope iss = iwh.Services.CreateScope())
    {
        IServiceProvider isp = iss.ServiceProvider;
        try
        {
            // IConfiguration c = ?????? 
            SeedData.Initialize(isp, c);
        }
        catch (Exception ex)
        {
            ILogger<Program> logger = isp.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred seeding the DB.");
        }
    }
    iwh.Run();
}

Question

How to obtain IConfiguration c from Main?

Upvotes: 2

Views: 3192

Answers (1)

Camilo Terevinto
Camilo Terevinto

Reputation: 32068

You would do just as you do for your MyContext service:

var configuration = isp.GetRequiredService<IConfiguration>();

It'd be better if you passed both dependencies to SeedData.Initialize instead of a dependency and the IoC container:

public static void Initialize(MyContext context, IConfiguration config)
{
    ...
}

IServiceProvider isp = iss.ServiceProvider;
try
{ 
    var configuration = isp.GetRequiredService<IConfiguration>();
    var context = isp.GetRequiredService<MyContext>();
    SeedData.Initialize(context, configuration);
}

With this, you at least avoid the Service Locator anti-pattern in the Initialize method.

Upvotes: 4

Related Questions