2017-03-25 8 views
0

接続可能なクライアントデータベースが複数あるWebAPI/EFコアバックエンドアプリケーションがあります(それぞれ同じスキーマですが、 。コントローラのアクションが呼び出されたときだけデータベース名がわかるときにDbContextを挿入

WebAPIコントローラにアクセスするまで、どのデータベースを接続するかはわかりません。この時点では、starup.csファイルのConfigureServices()メソッドのservices.AddDbContext <()への呼び出しを使用して、注入可能オブジェクトとしてDBContextを追加するのは遅すぎます。

DbContextの各インスタンスはリクエストごとに分離されるため、DbContextをDIを使用して渡すのではなく、コントローラのアクションから直接インスタンス化すると何か問題はありますか?

+2

法による場合は、次のようにあなたのコントローラでそれを使用する必要がありますすることができます接続するデータベースがWebApiの呼び出し全体で一貫していると判断した場合、それをDIですか? – DavidG

答えて

1

あなたは/

services.AddScoped<IDbContextFactory, DbContextFactory>(); 

それを登録DbContext

public interface IDbContextFactory 
{ 
    ApplicationContext Create(); 
} 

public class DbContextFactory() : IDbContextFactory, IDisposable 
{ 
    private ApplicationContext context; 
    private bool disposing; 

    public DbContextFactory(/* other dependencies here */) 
    { 
    } 

    public ApplicationContext Create(string tenantId) 
    { 
     if(this.context==null) 
     { 
      // and the connection string and replace the database name in it 
      // with the tenantId or whatever means you have to determine 
      // which database to access 
      string connectionString = ...; 

      var dbContextBuilder = new DbContextOptionsBuilder(); 
      dbContextBuilder.UseSqlServer(connectionString); 

      this.context = new ApplicationContext(dbContextBuilder); 
     } 

     return this.context; 
    } 

    public void Dispose(){ 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing){ 
     if (disposing){ 
      disposing?.Dispose(); 
     } 
    } 
} 

を作成するには、抽象ファクトリを使用して

public class MyController : Controller 
{ 
    private readonly IDbContextFactory contextFactory; 

    public MyController(IMyContextFactory contextFactory) 
    { 
     this.contextFactory = contextFactory; 
    } 

    public Task<IActionResult> GetSomeData(string tenantId) 
    { 
     var context = contextFactory.Create(tenantId); 

     return Ok(await context.Data.Where(...).ToListAsync()); 
    } 
} 
+0

これはまさに私が探していたものです。ありがとう! – mrtedweb

関連する問題