Как изменить имя базы данных dbContext из Cookies / Session - PullRequest
0 голосов
/ 30 июня 2019

У меня несколько пользователей с их собственной схемой базы данных, поэтому мы храним их ConnectionString в файле cookie / сессии, решение которого будет доступно.

Как я могу использовать HttpContext. Файлы cookie / данные сеанса для изменения строки подключения DBContext по запросу?

Контекст БД

public MyContext(string ConnectionString) : base(ConnectionString)
{

}

DependencyRegistrar

  public virtual void Register(ContainerBuilder builder, ITypeFinder typeFinder)
    {
    //data layer
        var dataSettingsManager = new DataSettingsManager();
        var dataProviderSettings = dataSettingsManager.LoadSettings();
        builder.Register(c => dataSettingsManager.LoadSettings()).As<DataSettings>();
        builder.Register(x => new EfDataProviderManager(x.Resolve<DataSettings>())).As<BaseDataProviderManager>().InstancePerDependency();

        builder.Register(x => x.Resolve<BaseDataProviderManager>().LoadDataProvider()).As<IDataProvider>().InstancePerDependency();

        if (dataProviderSettings != null && dataProviderSettings.IsValid())
        {
            var efDataProviderManager = new EfDataProviderManager(dataSettingsManager.LoadSettings());
            var dataProvider = efDataProviderManager.LoadDataProvider();
            dataProvider.InitConnectionFactory();

            builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();
        }
        else
            builder.Register<IDbContext>(c => new DBObjectContext(dataSettingsManager.LoadSettings().DataConnectionString)).InstancePerLifetimeScope();

        //repositories
        builder.RegisterGeneric(typeof(EfRepository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope();

1 Ответ

1 голос
/ 30 июня 2019

Вы должны быть в состоянии заменить:

отсюда: dataProviderSettings.DataConnectionString

builder.Register<IDbContext>(c => new DBObjectContext(dataProviderSettings.DataConnectionString)).InstancePerLifetimeScope();

с классом, который будет читать значение из куки.

Этот новый класс, очевидно, не будет контроллером, поэтому доступ к HttpContext должен быть достигнут с помощью: IHttpContextAccessor.

Для этого добавьте следующее:

public void ConfigureServices(IServiceCollection services)
{
     //other registrations
     services.AddHttpContextAccessor();
}

Тогда в вашем новом классе:

    public class ConnectionStringAccessor {
        private IHttpContextAccessor _httpContextAccessor;
        public ConnectionStringAccessor(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        public string GetConnectionString() {
            return  _httpContextAccessor.HttpContext.Request.Cookies["cookieName"].Value;
//you can consider some encryption/decryption or whatever you need to.
        }
    }

и, наконец,

builder.Register<IDbContext>(c => new DBObjectContext(c.Resolve<ConnectionStringAccessor >().GetConnecionString()).InstancePerLifetimeScope();

В данный момент VisualStudio недоступен, поэтому я поместил код без сборки или тестирования. Кроме того, ваш новый класс должен быть зарегистрирован в DI.

Для получения дополнительной информации, пожалуйста, обратитесь к этой статье: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-2.2

Просто чтобы подчеркнуть, как я уже сказал в комментарии, такой способ работы с такими разумными вещами, как строка подключения, крайне небезопасен.

...