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
- Registering components by conventions
- Registering components using Xml configuration, which can be combined with the code options
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