Saltar al contenido principal

Castle Windsor IoC Container

Castle Windsor is an open-source Inversion of Control (IoC) container for .NET applications.

It is a powerful and lightweight container that allows developers to implement the Dependency Injection (DI) pattern in their applications. Castle Windsor helps manage the creation and lifetime of objects, simplifying the process of building complex systems and promoting loose coupling between components.

History of Castle Windsor Framework

Castle Windsor was first released in 2004 by Krzysztof Koźmic under the Castle Project, which aimed to provide a set of useful tools and frameworks for .NET developers. It quickly gained popularity due to its simplicity and extensibility, becoming one of the most widely used IoC containers in the .NET ecosystem.

Features of Castle Windsor Framework

  1. Dependency Injection: Castle Windsor supports constructor injection, property injection, and method injection. It helps resolve dependencies between components, reducing the tight coupling between classes and promoting reusability.

    Example of constructor injection:

    public class FooService
    {
    private readonly IBarService _barService;

    public FooService(IBarService barService)
    {
    _barService = barService;
    }

    // ...
    }
  2. Component Registration: Castle Windsor provides a fluent API for registering components in the container. Developers can specify the lifetime of components (singleton, transient, per-thread, etc.), configure dependencies, and apply additional customizations.

    Example of component registration:

    var container = new WindsorContainer();
    container.Register(Component.For<IFooService>().ImplementedBy<FooService>().LifestyleSingleton());
  3. Convention-based Registration: Castle Windsor allows convention-based registration, where components are automatically registered based on naming conventions or attributes. This feature reduces the amount of manual configuration needed and promotes consistency across the application.

    Example of convention-based registration:

    container.Register(Classes.FromThisAssembly()
    .BasedOn<IService>()
    .WithService.DefaultInterfaces()
    .LifestyleTransient());
  4. Interceptors: Castle Windsor supports interceptors, which allow developers to add cross-cutting concerns (such as logging, caching, or security) to components without modifying their code. Interceptors can be applied globally or selectively to specific components.

    Example of interceptor registration:

    container.Register(Component.For<IFooService>()
    .ImplementedBy<FooService>()
    .Interceptors<LogInterceptor>());
  5. Configuration via XML or Code: Castle Windsor provides flexible configuration options. Developers can configure the container using XML files or through code, depending on their preference and project requirements.

    Example of XML configuration:

    <configuration>
    <components>
    <component id="fooService" service="MyApp.IFooService, MyApp" type="MyApp.FooService, MyApp" lifestyle="singleton" />
    </components>
    </configuration>
  6. Support for Child Containers: Castle Windsor supports the creation of child containers, allowing the composition of independent object graphs. Child containers inherit the registrations from their parent container but can also override or add new registrations.

    Example of child container usage:

    var parentContainer = new WindsorContainer();
    parentContainer.Register(Component.For<IFooService>().ImplementedBy<FooService>().LifestyleTransient());

    var childContainer = new WindsorContainer();
    childContainer.Register(Component.For<IBarService>().ImplementedBy<BarService>().LifestyleSingleton());

    childContainer.Parent = parentContainer;

    var fooService = childContainer.Resolve<IFooService>();

For more information on the Castle Windsor Framework, refer to the official website.

Examples of Castle Windsor Framework Usage

  1. Basic Component Registration:

    var container = new WindsorContainer();
    container.Register(Component.For<IFooService>().ImplementedBy<FooService>());
    var fooService = container.Resolve<IFooService>();
  2. Interceptor Usage:

    public class LogInterceptor : IInterceptor
    {
    public void Intercept(IInvocation invocation)
    {
    Console.WriteLine($"Executing method {invocation.Method.Name}");
    invocation.Proceed();
    Console.WriteLine($"Finished executing method {invocation.Method.Name}");
    }
    }

    container.Register(Component.For<IFooService>()
    .ImplementedBy<FooService>()
    .Interceptors<LogInterceptor>());
    var fooService = container.Resolve<IFooService>();
    fooService.DoSomething();
  3. Convention-based Registration:

    container.Register(Classes.FromThisAssembly()
    .BasedOn<IService>()
    .WithService.DefaultInterfaces()
    .LifestyleTransient());
    var services = container.ResolveAll<IService>();

These examples demonstrate some of the key features of Castle Windsor and how they can be used in real-world scenarios.

This concludes our tutorial on the Castle Windsor Framework. Remember to refer to the official documentation for more detailed explanations and advanced usage.