Jason Iwinski
Jason Iwinski

Reputation: 383

Component-specific Castle Windsor typed factory

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 IDbConnections 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:

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.

Upvotes: 1

Views: 967

Answers (1)

Roubachof
Roubachof

Reputation: 3401

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)));

Upvotes: 0

Related Questions