I have an application that uses several different database connections. I would like to use Castle Windsor's typed factory support to inject a factory that returns instances of IDbConnection
into my repositories and other components.
Here's how the interface for my typed factory looks like:
public interface IConnectionFactory
{
IDbConnection CreateConnection();
}
And here's a sample repository:
public class AccountRepository
{
private readonly IConnectionFactory connectionFactory;
public AccountRepository(IConnectionFactory connectionFactory)
{
this.connectionFactory = connectionFactory;
}
public Account FindAccountById(int id)
{
using (var connection = connectionFactory.CreateConnection())
{
// TODO use the connection here
}
}
}
And an excerpt of my component registration:
// ...
container.Register(Component.For<IDbConnection>()
.ImplementedBy<NpgsqlConnection>()
.LifestyleTransient());
container.Register(Component.For<IConnectionFactory>()
.AsFactory());
// ...
All my IDbConnection
s are implemented using the same type (NpgsqlConnection
), but I have several different connection strings I need to use. Ideally, I would like to setup Windsor to set the connection string on the IDbConnection
(or pass it into the connection constructor) for me depending on the component that has IConnectionFactory
as a dependency.
For example:
AccountRepository
and ItemRepository
, that take IConnectionFactory
as a dependency in their constructors.foo
and bar
.AccountRepository
calls IConnectionFactory.CreateConnection()
, I want it to return an IDbConnection
using connection string foo
. ItemRepository
calls IConnectionFactory.CreateConnection()
, I want it to return an IDbConnection
using connection string bar
.Is this possible with Castle Windsor?
I've researched this topic but haven't find any solution that fits my exact scenario. Ideally, I would like to keep my repositories ignorant of the exact connection string to use, i.e. I do not want to change my connection factory to:
public interface IConnectionFactory
{
IDbConnection CreateConnection(string connectionStringName);
}
I've also read all the documentation and articles I could find on ISubDependencyResolver
and ITypedFactoryComponentSelector
but I'm not sure if they are applicable in this scenario or how to piece everything together.
By the way, I am using Castle Windsor 3.1 and .NET 4.0.
Maybe use a real Factory, and not a typed one:
public ConnectionAFactory : IConnectionFactory
{
public ConnectionAFactory()
{
this.connectionString = "foo";
}
}
And register it in windsor with the correct Repository:
Component.For<AccountRepository>()
.DependsOn(
ServiceOverride.ForKey<IConnectionFactory>().Eq(typeof(ConnectionAFactory)));