2016-11-29 55 views
10

是否可以向Entity Framework 6的Configuration类注入依赖项?实体框架中的依赖注入种子方法?

例如,像这样:

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 
    } 
} 

或者更一般的方法是,以获得可能将代码注入甚至内部迁移:

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(...); 
    } 
} 

哪里是DI初始化发生在实体框架6定义那些绑定?

UPDATE

我不是问我应该使用什么。目前,我使用Ninject,但这是不可能的,因为无论我使用什么,我都应该能够将依赖性注入到迁移的构造函数中。如果你写的东西像我在上面的例子中写的那样,它会引发你关于“没有默认构造函数”的异常。

以上例子中的ILogger只是简单的依赖例子。如果你有IGeneratorService会产生一些数据,并且你想使用这个服务为Seed方法产生数据,事情会变得更糟。

+0

DI初始化应该由您的DI框架来处理。 –

+0

这个问题的任何部分如何回答这个问题? – eocron

+0

您是否尝试过使用任何DI框架? – ColinM

回答

5

实体框架6建议您使用的是.NET Framework 4.6或更低版本,并且.NET 4.6或更低版本没有内置的依赖注入功能,因此您必须使用第三方DI容器,如StructureMap,Ninject,这些DI容器为您提供了3种获得依赖注入的方法:通过构造函数,设置器或接口。

我不完全确定它是否可以使用构造函数注入来将依赖关系注入到ConfigurationInitialMigration类中,但我怀疑它。即使有可能,您也不能在您的问题中使用​​的方式注入:this._logger = logger,因为ILogger使用ILoggerFactory Create()方法进行初始化。

所以,我不认为它可能注入依赖到你的ConfigurationInitialMigration类使用构造函数注入一般。

如果你想在你的类使用​​,下面的代码片段应该工作:

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(...); 
    } 
} 
0

我不这么认为。当然不是在尝试从命令行使用update-database时。请记住,您的DI容器是在运行时注册的。没有任何服务会被注册到任何地方。除此之外,EF正在寻找一个带有无参数构造函数的配置文件。你可以用你问题中的例子快速测试这个。你会得到一个“在组件中找不到迁移配置类型'Your.Assembly”。

如果您正在专门寻找在种子方法中执行某项服务的操作,那么我会建议您查看回答了here的运行时api。

我在我的项目中使用了一个控制台应用程序,我可以在部署时发送命令作为构建管道的一部分。您可以在实际的代码库中轻松使用此方法。

private void RunMigrations() 
    { 
     Console.WriteLine("Starting migrations..."); 
     var configuration = new Configuration 
     { 
      TargetDatabase = new DbConnectionInfo(_connectionString, "System.Data.SqlClient") 
     }; 
     var dbMigrator = new DbMigrator(configuration); 
     dbMigrator.Update(); 
     Console.WriteLine("Migrations completed"); 

     //add your service here and do whatever you want. 
    } 

    private void Seed() 
    { 
     using (var MyContext = new MyContext(_connectionString)) 
     { 
      Console.WriteLine("Seeding test data into database"); 
      //this is a custom seed method 
      Initialize.Seed(_connectionString); 
      Console.WriteLine("Seeding test data is complete"); 

      //add your service here and do whatever you want. 
     } 
    }