Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Alternativa ao Web.config

Há alguma forma de se parametrizar os contextos dentro do código, nos abstendo do uso do Web.config? A ideia principal seria usar Dois Contextos. Um Contexto Global, e outro contexto individual,um para cada cliente. Este contexto individual atenderia N clientes, cada um com sua base de dados individual. Contudo, sempre atrelado ao mesmo Contexto Individual. As connections string ficariam guardadas no banco de dados de cada usuário, e no momento da conexão traríamos essa string direcionando para o Contexto correto, e para a base destinada àquele cliente/usuário, sem que precisemos ficar alterando o Web.config, que não vejo como seguro/confiável/estável.

4 respostas

Fala, Rafael, bom dia.

A string de conexão guarda o servidor (host), o banco de dados (database) e as credenciais de acesso. Imagino que apenas o banco de dados seja diferente por cliente, não?

Sendo assim você pode colocar o nome do banco em uma tabela de configurações que será acessada a partir do contexto global. Depois que recuperá-lo irá montar a string de conexão do cliente e injetá-la no contexto individual. Minha sugestão é que crie uma fábrica (Factory) para se encarregar de instanciar o contexto individual.

Abraços, Daniel

Bom dia Daniel!!

Cara, é exatamente isto. Somente o banco de dados será diferente. A ideia é exatamente esta, guardar as informações no banco e montar a string posteriormente. Contudo, devo injetar no web.config? Se não, como eu faço essa parametrização diretamente no contexto?

Neste caso,

solução!

Rafael, depois do login você precisa guardar o id do cliente na sessão ou token. Daí cria uma classe que será a fábrica de conexões para o cliente.

Escrevi um código aqui rapidinho pra tentar demonstrar isso.

Classe com a fábrica:

public class CustomerDatabaseFactory
    {
        public static DatabaseContext2 Create(
            IServiceProvider services, 
            IConfiguration config, 
            int idCliente)
        {
            DatabaseContext ctx = services.GetRequiredService<DatabaseContext>();
            //usar o ctx para gerar a string de conexão
            var cliente = ctx.Clientes.FirstOrDefault(c => c.Id == idCliente);
            var stringConexao = config.GetConnectionString("DbClientes").Replace("DatabaseName", cliente.DatabaseName);
            var options = new DbContextOptionsBuilder<DatabaseContext2>()
                .UseSqlServer(stringConexao)
                .Options;
            return new DatabaseContext2(options);

        }
    }

HomeController para gerar o contexto de clientes:

public class HomeController : Controller
    {
        DatabaseContext2 ctxClientes;

        public HomeController(IServiceProvider services, IConfiguration config)
        {
            var idCliente = 12; //pegar da sessão ou token
            ctxClientes = CustomerDatabaseFactory.Create(services, config, idCliente);
        }
}

Espero ter ajudado!

Show Daniel, elucidou excelentemente!!

Pelo que entendi ele muda "a quente" o banco de acesso. Era o que eu precisava!

Abraços e Obrigado!!!!