2016-10-24 14 views
10

Opracowuję prostą aplikację internetową i, w przyszłości, chcę to zrobić jako multi-tenancy..NET Core pobiera ciąg połączenia z appsettings.json

Więc chcę pisać ciąg połączenia prosto OnConfiguring metody: klasę

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

startowy:

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

Jak można wyodrębnić ciąg połączenia z appsettings.json do ApplicationContext klasie?

Nie chciałbym tworzyć żadnych konstruktorów dla klasy ApplicationContext.

+0

trzeba przekazać ciąg połączenia jako parametr do AddDbContext IIRC –

+0

Dlaczego chcesz zarejestrować go na 'metody OnConfiguring' zamiast w 'services.AddDbContext (options => options UseSqlServer (" ... "))'? – Tseng

+0

@ Tseng Potrzebuję zmienić dynamicznie ciągów połączenia w przyszłości dla wielu dzierżawy. –

Odpowiedz

5

Więc chcę pisać ciąg połączenia prosto metodą OnConfiguring:

Jak można Wyodrębniam ciąg połączenia z appsettings.json do klasy ApplicationContext?

Nie chciałbym tworzyć żadnych konstruktorów dla klasy ApplicationContext.

Można użyć Opcje Wzorzec poprzez IOptions ale najprostszym sposobem jest użycie DI w ApplicationContext konstruktora;)

Śledź poniżej artykułów, proszę:

8

Wyobraźmy sobie, że masz NET rdzenia aplikację i plik appsettings.json wygląda następująco:

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

Można uzyskać SqliteConnectionString wartość z Startup.cs tak:

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

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

, a następnie w Twój DBContext powinieneś dodać konstruktora, który akceptuje DbContextOptions:

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

    ... 
} 
+0

To dobrze. Ale jak mogę uzyskać ten sam ciąg w klasie "ApplicationContext"? Nie mogę tego zrobić, jak pisałeś. –

+3

A co jeśli chcę użyć konstruktora bez parametrów dla 'MyContext'? –

0

Możesz użyć wzoru fabrycznego, aby rozwiązać swój 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; 
    } 
} 

przy starcie:

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

swoją usługę lub sterownik:

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

Używam .NET Core 1.1.I to jest jak rozwiązać ten problem:

Dodaj ciąg połączenia do 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" 
    } 
} 

Potem stworzył klasę statyczną dostępu do właściwości ConnectionString z "gdziekolwiek":

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

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

Musiałem również dodać ten pakiet NuGet: System.Data.SqlClient

A następnie ustawiam ConnectionString propert rw Startup.cs:

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

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

a następnie można uzyskać dostęp ciąg połączenia poprzez: MyProject.Orm.ConnectionString

+1

Użyłem tego dla tego samego problemu w aplikacji .NET Core 2 i jest idealne. Wysoce zalecane. – Matt

Powiązane problemy