About Castle Windsor Container

Since I moved to Huddle, I am using Castle Windsor. This post is the summary of what I would learn while using Castle Windsor.

the source code

I don’t know why, but I found it difficult to find where the code is. It is here at https://github.com/castleproject. Even there is a stackoverflow question about where the code is.

Very descriptive error message

I often struggled with StructureMap error message, as it doesn’t tell you what went wrong. I like Windor’s, as it clearly states where it is screwed.

Can’t create component ‘LondonUbf.Installers.LoggerInterceptor’ as it has dependencies to be satisfied.

‘LondonUbf.Installers.LoggerInterceptor’ is waiting for the following dependencies:
– Service ‘LondonUbf.Domain.ExceptionLogger’ which was not registered.

Tutorials

There are a few tutorials. The link was in readme file of the project.

Use of Predicate

By the way, an example code in the tutorial uses Predicate, and it is interesting. I knew they exists, but didn’t really use it in my day-to-day coding.

[Test]
public void All_Controllers_Are_Registered()
{
    var allControllers = GetPublicClassesFromAssembly(c => c.Is<IController>());
    var registeredControllers = GetImplementaionTypesFor(typeof (IController), _containerWithControllers);
 Assert.That(allControllers, Is.EqualTo(registeredControllers));
}
private Type[] GetPublicClassesFromAssembly(Predicate<Type> where)
{
    return typeof (HomeController).Assembly.GetExportedTypes()
        .Where(t => t.IsClass)
        .Where(t => t.IsAbstract == false)
        .Where(where.Invoke)
        .OrderBy(t => t.Name)
        .ToArray();
}

By accepting Predicate parameter, you can make the method to accept lamda filter. This is the source of Predicate. It is delegate that returns boolean value.

namespace System
{
    /// <summary>
    /// Represents the method that defines a set of criteria and determines whether the specified object meets those criteria.
    /// </summary>
    ///
    /// <returns>
    /// true if <paramref name="obj"/> meets the criteria defined within the method represented by this delegate; otherwise, false.
    /// </returns>
    /// <param name="obj">The object to compare against the criteria defined within the method represented by this delegate.</param><typeparam name="T">The type of the object to compare.This type parameter is contravariant. That is, you can use either the type you specified or any type that is less derived. For more information about covariance and contravariance, see Covariance and Contravariance in Generics.</typeparam><filterpriority>2</filterpriority>
    public delegate bool Predicate<in T>(T obj);
}

Registering interfaces

Not much different from other IoC containers like Ninject and StructureMap.

public class RepositoriesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<FileNameParser, IMessageParser>());
        container.Register(
            Component.For<MessageRepository, IMessageRepository>()
            .DependsOn(new { messageDirectory = HostingEnvironment.MapPath("/Content/messages")})
            );
    }
}

If your class depends on any other variable, you can use .DependsOn to resolve it. In the above example, I used HostingEnvironment.MapPath to find out the directory of “messages”. It doesn’t require HttpContext, unlike Server.MapPath(…).

cf) The difference betweeen Server.MapPath and HostingEnvironment.MapPath(…): http://stackoverflow.com/questions/944219/what-is-the-difference-between-server-mappath-and-hostingenvironment-mappath

Dynamic Proxy

where T: class, new()

It is a constraint on the generic parameter that T must be a class and have an parameterless default constructor. (from Stackoverflow)

The DP tutorial example used this syntax.

public static TFreezable MakeFreezable<TFreezable>() where TFreezable : class, new()
{
    var freezableInterceptor = new FreezableInterceptor();
    var proxy = _generator.CreateClassProxy<TFreezable>(new CallLoggingInterceptor(), freezableInterceptor);
    _freezables.Add(proxy, freezableInterceptor);
    return proxy;
}

It is surprisingly simple to intercept a call to method. Just add .Interceptors() to the component registration.

container.Register(
    Component.For<MessageRepository, IMessageRepository>()
    .DependsOn(new { messageDirectory = HostingEnvironment.MapPath("/Content/messages")})
    .Interceptors<MessageRepositoryInterceptor>()
    );

The interceptor is a simple class.

public class MessageRepositoryInterceptor : IInterceptor
{
    private readonly ExceptionLogger _logger;

    public MessageRepositoryInterceptor(ExceptionLogger logger)
    {
        _logger = logger;
    }

    public void Intercept(IInvocation invocation)
    {
        try
        {
            _logger.Log(string.Format("{0}.{1},  Message: {2} ", invocation.TargetType.Name, invocation.Method.Name, invocation.Arguments[0]));
            invocation.Proceed();
        }
        catch(Exception ex)
        {
            _logger.Log(ex);
            throw;
        }
    }
}

the Life cycle of objects

Quite bluntly saying, if you inject your dependencies into constructor of a class, those dependent objects are disposed together when the class gets disposed. However, if you use resolve a dependency manually, using .Resolve(), you have to release it manually.

About Castle Windsor Container

2 thoughts on “About Castle Windsor Container

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s