2016-11-29 1 views
10

Entity Framework 6のConfigurationクラスに依存関係を挿入することは可能ですか?このような例Entity Frameworkのシードメソッドへの依存性注入?

:DI初期ある

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

を定義するエンティティフレームワーク6で起こる:

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

以上の一般的なアプローチは、コードも内部移行を注入する可能性を得ることですそれらの束縛?

UPDATE

イムではない、私が使うべきかについて尋ねます。現在、私はNinjectを使用していますが、それは問題ではありません。何を使用していても、移行のコンストラクタに依存関係を注入できるはずです。もし私が上記の例で書いたようなものを書いているのであれば、 "デフォルトのコンストラクタはありません"という例外がスローされます。

上記のILoggerは、依存関係の単なる単なる例です。いくつかのデータを生成するIGeneratorServiceがあり、このメソッドを使用してSeedメソッドのデータを生成したい場合は、状況が悪化します。

+0

DI初期化は、DIフレームワークで処理する必要があります。 –

+0

この質問のどの部分に対してもこの回答はどのようにして返されますか? – eocron

+0

DIフレームワークを使ってみましたか? – ColinM

答えて

5

Entity Frameworkの6あなたは以下の.NET Framework 4.6以上を使用していることを示唆していると、内蔵された以下の.NET 4.6のためにあなたは、このようなのStructureMap、Ninject、などのサードパーティのDIコンテナを使用する必要がありますので、何の依存性の注入能力がありませんコンストラクタ、セッター、またはインターフェイスを介して:などこれらのDIコンテナはあなたに依存性の注入を取得するための3つの方法を与えます。

コンストラクタインジェクションを使用してConfigurationまたはInitialMigrationクラスに依存関係を注入することが可能かどうかは完全にはわかりませんが、私はそれを疑っています。 ILoggerですがILoggerFactory Create()方法を使用して初期化されているのでthis._logger = logger:それは可能であっても、あなたは​​あなたがあなたの質問に記述する方法を注入することができません。

したがって、一般的にコンストラクタインジェクションを使用して、ConfigurationまたはInitialMigrationクラスに依存性を注入することはできません。

あなたのクラスで​​を使用したい場合は、次のコードスニペットは動作するはずです:

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