2

Let's get straight. I have interface and class like this:

public interface IDataBase
{
    DataTable GetSomeTableData();
}

My class:

public class DataBase : IDataBase    
{
    private readonly string _connectionString;

    public DataBase(string connectionString)
    {
        this._connectionString = connectionString;
    }

    public DataTable GetSomeTableData()
    {
        using (SqlConnection cn = new SqlConnection(_connectionString))
        {
             cn.Open();
             // some select
        }
    }
}

I'm using Autofac to inject that class:

var builder = new ContainerBuilder();
builder.RegisterType<DataBase>().As<IDataBase>).WithParameter("connectionString", "my connection string");
var container = builder.Build();
var database = container.Resolve<IDataBase>();
var tableData1 = database.GetSomeTableData();
// change connection string ?????????????????
var tableData2 = database.GetSomeTableData();

I need to get table data from one DB and another DB. How can I change connection string after have registered class? You may give another exapmle..

1 Answers1

11

There are many ways to do it. One would be to create and inject a service instead of just plain connection string.

public interface IConnectionStringProvider
{
    public string ConnectionString { get; set }
}

public class ConnectionStringProvider
{
    public string ConnectionString { get; set }
}


var builder = new ContainerBuilder();
builder.RegisterType<DataBase>()
    .As<IDataBase>);
builder.RegisterType<ConnectionStringProvider>)
    .As<IConnectionStringProvider>
    .SingleInstance();

var container = builder.Build();
var database = container.Resolve<IDataBase>();
var connStringProvider = container.Resolve<IConnectionStringProvider>();
var tableData1 = database.GetSomeTableData();
connStringProvider.ConnectionString = "...";
var tableData2 = database.GetSomeTableData();

The DataBase would then use that service:

public class DataBase : IDataBase    
{
    private readonly IConnectionStringProvider _connectionStringProvider;

    public DataBase(IConnectionStringProvider connectionStringProvider)
    {
        this._connectionStringProvider = connectionStringProvider;
    }

    public DataTable GetSomeTableData()
    {
        using (SqlConnection cn = new SqlConnection(_connectionStringProvider.ConnectionString))
        {
             cn.Open();
             // some select
        }
    }
}
Jacek Gorgoń
  • 3,206
  • 1
  • 26
  • 43
  • What if the connectionstring is build up depending on the user that is logged in? I'm developing an application where there is a database per Customer of ours, Databases are identical, So its a same DbContext connectionstring with a different uid and pwd. So after a user is logged in in need a connection to the right db. – edgarpetrauskas Jan 19 '15 at 09:54
  • 1
    The idea stays the same. Extend the ConnectionStringProvider to hold uid/pwd and return calculated conn string. One dependency will set those the credentials on the provider, while other will use the conn string it gives. – Jacek Gorgoń Jan 19 '15 at 16:03
  • Of course. Typically you inject a DbContext per web request or per batch job. – Jacek Gorgoń Jun 16 '16 at 16:42