Reputation: 15101
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();
}
How to obtain IConfiguration c
from Main
?
Upvotes: 2
Views: 3192
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