This project is read-only.

named items in the container

Oct 15, 2013 at 10:09 PM
In my project I have two disparate datasources, but both are SQL Server. In other words, one connection points to SQL Server A and the second to SQL Server B. How can I 'know' what connection to get when I go to resolve my connection? I was thinking maybe named items in the container when I register them. There wasn't an obvious way to do this but I really need/want to be able to get the appropriate connection at run time based on what request is being made. Hopefully the question makes sense.
Oct 15, 2013 at 10:38 PM
There are multiple solutions for this. Which one is best depends on the exact requirements. Since you need to switch based on the request (meaning that each request will only use a single connection string), you might want to hide the creation of the connection behind an abstraction and let this abstraction decide which connection string to use. Here's an example:
public interface IConnectionFactory
{
    SqlConnection CreateConnection();
}
Within your web application you can create an implementation of this interface:
public class AspNetConnectionFactory : IConnectionFactory
{
    private readonly string conStr1;
    private readonly string conStr2;

    public AspNetConnectionFactory(string conStr1, string conStr2)
    {
        this.conStr1 = conStr1;
        this.conStr2 = conStr2;
    }

    public SqlConnection CreateConnection()
    {
        return new SqlConnection(this.GetConnectionStringForCurrentRequest());
    }

    private string GetConnectionStringForCurrentRequest()
    {
        return [here your selection logic] ? conStr1 : conStr2;
        // for instance: HttpContext.Current..Url.Host.Contains("customer1.com")
    }
}
You can register this AspNetConnectionFactory as follows:
string conStr1 = ConfigurationManager.ConnectionStrings["customer1"].ConnectionString;
string conStr2 = ConfigurationManager.ConnectionStrings["customer2"].ConnectionString;
container.RegisterSingle<IConnectionFactory>(new AspNetConnectionFactory(conStr1, conStr2));
But perhaps you're registering an Entity Framework DbContext per web request. You might get away with this registration:
container.RegisterPerWebRequest<MyDbContext>(
    () => new MyDbContext([here your selection logic] ? conStr1 : conStr2));
There are many variations of this pattern, but hopefully this gives you some ideas.

Also take a look at this related question and this question about multi-tenancy.
Marked as answer by dot_NET_Junkie on 2/26/2014 at 1:19 PM
Oct 15, 2013 at 10:56 PM
Thank you for the quick response. I should have specified a little more that I will be using both connections during the course of my work. The work is happening in a windows service. Depending on the request that came in I may need both or just one of the connections.

In any case I see where you are going with this, but doesn't it leave me to manage my own lifetime, essentially giving out a new connection for each and every request to the container. Even if I was in a web application this seems like the case.

I will review the two links and reply back if they solve the problem. I believe the related question may do the trick.
Oct 17, 2013 at 3:22 PM
Ok got this to work using a separate class representing each connection. and of course it has the additional feature of making sure the code 'reads' clear. This query uses this connection, this query uses the other connection. very nice. I'll clean up/refactor my implementation later.