.NET Core получает строку подключения из 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);
    }
}

Класс запуска:

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

Как я могу извлечь строку подключения из appsettings.json в класс ApplicationContext?

Я бы не хотел создавать какие-либо конструкторы для класса ApplicationContext.

Ответ 1

Итак, я хочу написать строку подключения прямо в методе OnConfiguring:

Как я могу извлечь строку подключения из appsettings.json в класс ApplicationContext?

Я бы не хотел создавать какие-либо конструкторы для класса ApplicationContext.

Вы можете использовать Шаблон параметров через IOptions, но самый простой способ - использовать DI в конструкторе ApplicationContext;)

Следуйте ниже, пожалуйста,

Ответ 2

Предположим, что у вас есть приложение .NET Core, а ваш файл appsettings.json выглядит следующим образом:

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

Вы можете получить SqliteConnectionString значение из Startup.cs следующим образом:

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

    ...
}

Ответ 3

Вы можете использовать шаблон factory, чтобы разрешить ваш 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...
    }
}

Ответ 4

Я использую .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:

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

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

И затем вы можете получить доступ к строке подключения через: MyProject.Orm.ConnectionString