Reputation: 3450
I develop a simple web app and, in the future, I want to do it as multi-tenancy.
So I want to write the connection string straight into OnConfiguring
method:
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);
}
}
Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationContext>();
services.AddMvc();
}
How can I extract connection string from appsettings.json
into ApplicationContext
class?
I wouldn't like to create any constructors for ApplicationContext
class.
Upvotes: 25
Views: 61781
Reputation: 6809
.NET Core 2.0
Add this class:
// Requires NuGet package Microsoft.Extensions.Configuration.Json
using Microsoft.Extensions.Configuration;
using System.IO;
namespace RutarBackgroundServices.AppsettingsJson
{
public static class AppSettingsJson
{
public static string ApplicationExeDirectory()
{
var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
var appRoot = Path.GetDirectoryName(location);
return appRoot;
}
public static IConfigurationRoot GetAppSettings()
{
string applicationExeDirectory = ApplicationExeDirectory();
var builder = new ConfigurationBuilder()
.SetBasePath(applicationExeDirectory)
.AddJsonFile("appsettings.json");
return builder.Build();
}
}
}
Get the value for the key "MssqlConnectionString" from the "appsettings.json" file:
var appSettingsJson = AppSettingsJson.GetAppSettings();
var connectionString = appSettingsJson["MssqlConnectionString"];
Create the file "appsettings.json" in the root directory of your project:
{
"MssqlConnectionString": "Server=yourip; Database=yourdbname; User Id=yourusername; Password=yourpassword; Pooling=true;",
"Db2ConnectionString": "Database=yourdbname;UserID=yourusername;Password=yourpassword;Server=yourip:yourport",
"SomeOtherKey": "SomeOtherValue"
}
Upvotes: 11
Reputation: 7350
So I want to write the connection string straight into OnConfiguring method:
How can I extract connection string from appsettings.json into ApplicationContext class?
I wouldn't like to create any constructors for ApplicationContext class.
You could use Options Pattern via IOptions
but the easiest way is using DI in ApplicationContext
constructor ;)
Follow below articles, please:
Upvotes: 4
Reputation: 64150
You can use the factory pattern to resolve your 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;
}
}
In Startup:
services.AddDbContext<ApplicationContext>();
services.AddScoped<ITenantDbContextFactory, TenantDbContextFactory>();
Your service or controller:
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...
}
}
Upvotes: 2
Reputation: 410
Let's imagine that you have .NET Core application and your appsettings.json
file looks like this:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"Production": {
"SqliteConnectionString": "Filename=./MyDatabase.sqlite"
}
}
You can get SqliteConnectionString
value from Startup.cs
like this:
public void ConfigureServices(IServiceCollection services)
{
var connection = Configuration["Production:SqliteConnectionString"];
services.AddDbContext<MyContext>(options =>
options.UseSqlite(connection)
);
....
}
And then in your DBContext
you should add constructor that accepts DbContextOptions
:
public class MyContext : DbContext
{
public MyContext (DbContextOptions<MyContext> options) : base(options)
{ }
...
}
Upvotes: 23