2016-11-29 100 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. 
     } 
    }