Getting IHostingEnvironment.ContentRootPath inside DatabaseInitializer

.net-core asp.net-core entity-framework-core

Question

I'm trying to seed my db with some data stored in json files.

I need to inject an IHostingEnvironment inside my IDatabaseInitializer.Seed() method so I can read the json files using IHostingEnvironment.ContentRootPath.

This property is injected by the main container by default but the constructor of an DbConfiguration must be parameterless, so I can't pipe IHostingEnvironment through DbConfiguration into SetDatabaseInitializer(new DatabaseInitializer()).

/*
* Database Context
*/
[DbConfigurationType(typeof(DatabaseConfiguration))]
public class DatabaseContext : DbContext
{
    public DbSet<User> Users { get; set; }

    public DatabaseContext(string nameOrConnectionString) : base(nameOrConnectionString) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    }
}

/*
* Database Configuration
*/
public class DatabaseConfiguration : DbConfiguration
{
    // Can't receive injected IHostingEnvironment env because constructor must be parameterless
    public DatabaseConfiguration()
    {
        SetProviderServices("System.Data.SqlClient", SqlProviderServices.Instance);

        // Could pass IHostingEnvironment through constructor
        SetDatabaseInitializer(new DatabaseInitializer()); 
    }
}

/*
* Database Initializer
*/
public class DatabaseInitializer : DropCreateDatabaseAlways<DatabaseContext>
{
    private readonly IHostingEnvironment env;

    // Receives IHostingEnvironment from DatabaseConfiguration
    public DatabaseInitializer(IHostingEnvironment env)
    {
        this.env = env;
    }

    protected override void Seed(DatabaseContext context)
    {
        // Read some .json files
    }
}
1
2
1/18/2017 10:20:08 PM

Popular Answer

I'm initializing my db, and had to write a separate class, which I call from configure, you could do the same thing and pass in the path as a parameter

Here's how I call it:

        using (var scope = scopeFactory.CreateScope())
        {
            // Initialise Database
            var initializer = scope.ServiceProvider.GetService<IDbInitializer>();
            initializer.SeedAsync().Wait();

            // initialize plugin manager
            var manager = scope.ServiceProvider.GetService<IPluginManager>();
            manager.Initialize(dbConnection);
            if (Configuration.GetSection("PluginService").GetValue<bool>("RunAtStartup") == true)
                manager.Start();
        }

and here's the db initialize class

    public interface IDbInitializer
{
    Task SeedAsync();
}

public class DbInitializer : IDbInitializer
{
    private ApplicationDbContext _context;
    private RoleManager<IdentityRole> _roleManager;
    private UserManager<ApplicationUser> _userManager;

    public DbInitializer(ApplicationDbContext context,
                         RoleManager<IdentityRole> roleManager,
                         UserManager<ApplicationUser> userManager)
    {
        _context = context;
        _roleManager = roleManager;
        _userManager = userManager;
    }

    public async Task SeedAsync()
    {
        await CreateRolesAsync();
        await CreateAdminUserAsync();
        await SeedMenuAsync();
    }

    private async Task CreateRolesAsync()
    {
        List<IdentityRole> roles = new List<IdentityRole>();
        roles.Add(new IdentityRole { Name = "Admin", NormalizedName = "ADMINISTRATOR" });
        roles.Add(new IdentityRole { Name = "Member", NormalizedName = "MEMBER" });                     // An email confirmed memeber
        roles.Add(new IdentityRole { Name = "Guest", NormalizedName = "GUEST" });                       // Used for a user that has only checked out as guest
        roles.Add(new IdentityRole { Name = "NotConfirmed", NormalizedName = "NOTCONFIRMED" });         // Used when a guest hasnt confirmed there registration

        foreach (var role in roles)
        {
            var roleExists = await _roleManager.RoleExistsAsync(role.Name);
            if (!roleExists)
            {
                await _roleManager.CreateAsync(role);
            }
        }
    }

    ...

Hope that helps

0
5/31/2017 10:35:54 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow