Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection into Entity Framework seed method?

Is it possible to inject dependencies into Configuration class of Entity Framework 6?

For example, like this:

internal sealed class Configuration : DbMigrationsConfiguration<MyBaseContext>
{
    private readonly ILogger _logger;

    public Configuration(ILogger logger)
    {
        this._logger = logger;
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(Home.DAL.Data.HomeBaseContext context)
    {
         //log something
    }
}

Or more general approach is to obtain possibility to inject code even inside migrations:

public partial class InitialMigration : DbMigration
{        
    private readonly ILogger _logger;

    public InitialMigration(ILogger logger)
    {            
         this._logger = logger;
    }

    public override void Up()
    {
        CreateTable(...);
    }

    public override void Down()
    {
        DropTable(...);
    }
}

Where is DI initialization happens in Entity Framework 6 to define those bindings?

UPDATE

Im not asking about what I should use. Currently, Im using Ninject but that's out of the question, because whatever I use, I should be able to inject dependecies into constructor of migrations. Of courser if you write something like I wrote in example above it will just throw you exception about "no default constructor".

ILogger in above example is just simple example of dependency. Things go worse if you have IGeneratorService which will generate some data and you want to use this service to generate data for Seed method.

like image 953
eocron Avatar asked Nov 29 '16 12:11

eocron


People also ask

Why is seed data useful for testing ASP NET core applications?

Creating Seed Data for ASP.NET Applications. When creating a new application I almost always need to have some initial seed data created when I first run or begin developing an application. This data helps create a baseline for all developers on an application and makes it easier to bring on new coders to the team.

What is seed method in MVC?

This seed() method in configuration. cs is called when you run update-database in the Package Manager Console. It's also called at application startup if you change Entity Framework to use the MigrateDatabaseToLatestVersion database initializer.

What is data seeding in database?

Data seeding is the process of populating a database with an initial set of data. There are several ways this can be accomplished in EF Core: Model seed data. Manual migration customization. Custom initialization logic.


1 Answers

Entity Framework 6 suggests that you are using .NET Framework 4.6 or below and there is no dependency injection capability built-in for .NET 4.6 or below so you have to use third-party DI containers such as StructureMap, Ninject, etc. Those DI containers give you 3 ways to get dependency injection: through the constructor, setter, or interface.

I'm not entirely sure if its possible to use constructor injection to inject dependencies into Configuration or InitialMigration class, but I doubt it. Even if it is possible, you wouldn't be able to inject ILogger the way you describe in your question: this._logger = logger because ILogger is initialized using ILoggerFactory Create() method.

So, I don't think its possible to inject dependencies into your Configuration or InitialMigration classes using constructor injection in general.

If you want to use ILogger in your classes, the following code snippets should work:

internal sealed class Configuration : DbMigrationsConfiguration<MyBaseContext>
{
    private readonly ILogger _logger;

    public Configuration(ILoggerFactory loggerFactory)
    {
        this._logger = loggerFactory.Create("ConfigurationLogger");
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(Home.DAL.Data.HomeBaseContext context)
    {
         //log something
         _logger.WriteInformation("Seeding data.");
    }
}

public partial class InitialMigration : DbMigration
{        
    private readonly ILogger _logger;

    public InitialMigration(ILoggerFactory loggerFactory)
    {            
         this._logger = loggerFactory.Create("InitialMigrationLogger");
    }

    public override void Up()
    {
        _logger.WriteInformation("Create table.");
        CreateTable(...);
    }

    public override void Down()
    {
        _logger.WriteInformation("Drop table.");
        DropTable(...);
    }
}
like image 55
kimbaudi Avatar answered Sep 20 '22 20:09

kimbaudi