2016-10-24 12 views
10

私はシンプルなWebアプリケーションを開発していますが、将来はマルチテナントとしてやりたいと思います。.NETコアget appsettings.jsonから

だから私はストレートOnConfiguringメソッドへの接続文字列を書きたい:

public class ApplicationContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    { 
     optionsBuilder.UseSqlServer("connection string from appsettings.json"); 
     base.OnConfiguring(optionsBuilder); 
    } 
} 

スタートアップクラス:私はApplicationContextクラスにappsettings.jsonから接続文字列を抽出することができますどのように

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext<ApplicationContext>(); 
    services.AddMvc(); 
} 

ApplicationContextクラスのコンストラクタを作成したくありません。

+0

あなたはそれを 'OnConfiguring'メソッドを登録したいのはなぜAddDbContext IIRC –

+0

にパラメータとして接続文字列を渡す必要があります'services.AddDbContext (options => options.UseSqlServer(" ... "))'ではなく? – Tseng

+0

@Tsengマルチテナントのために動的に接続文字列を変更する必要があります。 –

答えて

5

は、だから私はストレートOnConfiguringメソッドへの接続文字列を書きたいですappsettings.jsonから接続文字列を抽出しますApplicationContextクラスに?

私はApplicationContextクラスのコンストラクタを作成したくありません。

あなたはIOptions経由オプションパターンを使用することができますが、最も簡単な方法は、ApplicationContextコンストラクタでDIを使用している;)

フォロー記事、ください以下:

8

のは、あなたが.NETのコアアプリケーションとappsettings.jsonファイルは次のようになりますしていることを想像してみましょう:

{ 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Debug", 
     "System": "Information", 
     "Microsoft": "Information" 
    } 
    }, 
    "Production": { 
    "SqliteConnectionString": "Filename=./MyDatabase.sqlite" 
    } 
} 

あなたはこのようStartup.csからSqliteConnectionString値を取得することができます

public void ConfigureServices(IServiceCollection services) 
{ 
    var connection = Configuration["Production:SqliteConnectionString"]; 

    services.AddDbContext<MyContext>(options => 
     options.UseSqlite(connection) 
    ); 
    .... 
} 

そして中DBContextを受け入れるコンストラクタを追加する必要があります。DbContextOptions

public class MyContext : DbContext 
{ 
    public MyContext (DbContextOptions<MyContext> options) : base(options) 
    { } 

    ... 
} 
+0

いいですね。しかし、どうすれば同じ文字列を 'ApplicationContext'クラスに入れることができますか?あなたが書いたように私はそれをすることができません。 –

+3

そして、MyContextにパラメータのないコンストラクタを使用したいのですが? –

0

工場パターンを使用してDbContextを解決することができます。スタートアップで

public interface ITenantDbContextFactory 
{ 
    ApplicationContext Create(string tenantId); 
} 

public class TenantDbContextFactory() 
{ 
    private ApplicationContext context; 

    public TenantDbContextFactory() 
    { 
    } 

    public ApplicationContext Create(string tenantId) 
    { 
     if(this.context==null) 
     { 
      var connectionString = GetConnectionForTenant(tenantId); 
      var dbContextBuilder = new DbContextOptionsBuilder(); 
      dbContextBuilder.UseSqlServer(connectionString); 

      this.context = new ApplicationContext(dbContextBuilder); 
     } 

     return this.context; 
    } 
} 

services.AddDbContext<ApplicationContext>(); 
services.AddScoped<ITenantDbContextFactory, TenantDbContextFactory>(); 

あなたのサービスやコントローラー:

どのように行うことができます

public class HomeController 
{ 
    private readonly ITenantDbContextFactory dbFactory; 
    public HomeControler(ITenantDbContextFactory tenantDbContextFactory) 
    { 
     this.dbFactory = tenantDbContextFactory; 
    } 

    public void Action() 
    { 
     var dbContext = this.dbFactory.Create("tenantA"); 
     // use your context here 
     dbContext... 
    } 
} 
0

私は.NET Core 1.1を使用しています。そして、これは私は、この問題を解決する方法である:

appsettings.jsonに接続文字列を追加します。

{ 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Warning" 
    } 
    }, 
    "ConnectionStrings": { 
    "MyConnectionString": "Data Source=yourIp,1433;Initial Catalog=yourCatalog;Integrated Security=True;User Id=yourUser;Password=yourPassword;MultipleActiveResultSets=True" 
    } 
} 

それから私は「どこでも」からConnectionStringプロパティにアクセスするための静的クラスを作成しました:

namespace MyProject.Orm 
{ 
    public static class DatabaseConnection 
    { 
     public static string ConnectionString { get; set; } 

     public static SqlConnection ConnectionFactory() 
     { 
      return new SqlConnection(ConnectionString); 
     } 
    } 
} 

私はまた、このNuGetパッケージを追加する必要がありました:System.Data.SqlClient

そして次に私はConnectionStringのプロパティを設定しましたStartup.csのY:

public void ConfigureServices(IServiceCollection services) 
     { 
      // Add framework services. 
      services.AddMvc(); 

      Orm.DatabaseConnection.ConnectionString = Configuration["ConnectionStrings:MyConnectionString"]; 
     } 

そしてあなたが経由して接続文字列にアクセスすることができます。MyProject.Orm.ConnectionString

+1

.NET Core 2アプリケーションでこの問題にこれを使用しました。これは完璧です。強くお勧めします。 – Matt

関連する問題