Castle Windsor: How to register components

Created on April 22, 2012.

You can register your components in the following ways:

Registering components one-by-one

// Initialize the container
var container = new WindsorContainer();

// Register your component with the desired lifestyle
container.Register(Component.For<IComponent>()
                       .ImplementedBy<Component>()
                       .LifestylePerThread());

What about open generic types?

// Initialize the container
var container = new WindsorContainer();

// Register your component for instance with the default lifestyle = Singleton
container.Register(Component.For(typeof (IRepository<>)
                       .ImplementedBy(typeof (Repository<>));

How to replace an allready registered component?

In Windsor you can simple register it again, the last registered component will be the one used

// Initialize the container
var container = new WindsorContainer();

// Register your component for instance with a lifestyle
container.Register(Component.For(typeof (IRepository<>)
                       .ImplementedBy(typeof (Repository<>)
                       .LifestylePerWebRequest());

// Register a specialized CustomerRepository
container.Register(Component.For<IRepository<Customer>>()
                       .ImplementedBy<CustomerRepository>()
                       .LifestylePerWebRequest());

How to make one class resolvable by two interface but have them share the same instance?

// Initialize the container
var container = new WindsorContainer();

// Register your component
container.Register(Component.For<IRepository<Customer>, ICustomerRepository>()
                       .ImplementedBy<CustomerRepository>()
                       .LifestylePerWebRequest());

How can i use the decorator pattern?

First let’s create a logging decorator

public class LoggingCustomerRepository : IRepository<Customer>
{
  public ILogger Logger { get; set; };
  public IRepository<Customer> Repository { get; private set; }

  public LoggingCustomerRepository(IRepository<Customer> repository)
  {
    this.Repository = repository;
  }

  public Customer this[int id]
  {
    get { return Repository[id]; }
  }

  public void Add(Customer instance)
  {
    logger.Debug("Adding customer");
    Repository.Add(instance);
  }
}

With Castle Windsor the order of the registrations enables this behavior, so the first implementation will be injected into the decorator.

// Initialize the container
var container = new WindsorContainer();

// Register the default implementation
container.Register(Component.For<IRepository<Customer>()
                       .ImplementedBy<CustomerRepository>()
                       .LifestylePerWebRequest());

// Now register the decorator
container.Register(Component.For<IRepository<Customer>()
                       .ImplementedBy<LoggingCustomerRepository>()
                       .LifestylePerWebRequest());

Registering components by conventions

To do exactly the same but with conventions syntax

// Initialize the container
var container = new WindsorContainer();

// Register all non abstract class inheriting from IRepository with all interfaces
// as service, so resolvable by all interfaces
container.Register(Classes.FromThisAssembly()
                       .BasedOn(typeof(IRepository<>))
                       .WithServiceAllInterfaces());

WithServiceAllInterfaces: Means windsor will register the component bound to all it’s interfaces, so if for instance your CustomerRepository implements IRepository<Customer> but also ICustomerRepository, when you resolve an instance, it will be shared across both contracts for the specified lifetime ( transient means no sharing )

Using installers

Installers provide you a way to group related registrations into one class, to create an installer simply create a class and implement IWindsorInstaller, like this:

using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;

namespace Windsor.Tests.Generics
{
  public class RepositoryInstaller : IWindsorInstaller
  {
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
      container.Register(Classes.FromThisAssembly()
                            .BasedOn(typeof(IRepository<>))
                            .WithServiceAllInterfaces());
    }
  }
}

To use this installer simple install it on your container instance

// Initialize the container
var container = new WindsorContainer();

// Install the installer(s)
container.Install(new RepositoryInstaller());

Next

Castle Windsor: Facilities and specialized resolving

Previous

Castle Windsor: Avoid memory leaks by learning the underlying mechanics