Continuing from my previous post… Using Custom Dependency Resolvers and Sub Kernels. I think this is more of an edge case, but the fact that I can be done really easily is where the Castle strength is.

First, I see two nice things about Sub Kernels, they can be used by themselves or added as a child to another Kernel, meaning for testing and other uses, the Kernel can be completely hidden. Next, when added as a child, dependencies that live in the parent container can be used by types in the child container, automatically. I don’t know if there are any guide lines as to when to use a Sub Kernel, but I would consider it when you have a custom facility or a factory class which stores a lot of types or if you need to customize the Kernel in some way. Using a container is as easy as creating the class and allowing a Kernel to be passed in a Constructor when needed.

private readonly IKernel _container = new DefaultKernel();</p>



public MyFactory() {

_container.Resolver.AddSubResolver(<span class="kwrd">new</span> CaseInsensitiveDependencyResolver());

}

public MyFactory(IKernel parent) : this()
{

parent.AddChildKernel(_container);

}

Secondly, Customizing the Kernel with a CustomDependencyResolver, is easy and very useful when you need to do that. In this case I have a simple Resolver which looks at the additional parameter dictionary (passed to the Resolve Methods) and looks for a match ignoring case. I just needed to implement the ISubDependencyResolver interface which only has two methods, and register it on the container using Resolver.AddSubResolver (You can also overwrite the main Resolver when the Kernel is created). SubResolvers should return null if they didn't resolve the dependency, the main Resolver will throw an error if it's a required dependency.

internal class CaseInsensitiveDependencyResolver : ISubDependencyResolver
{
    public object Resolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model,
                          DependencyModel dependency)
    {
        foreach (DictionaryEntry entry in context.AdditionalParameters)
            if (dependency.DependencyKey.Equals(entry.Key as string, StringComparison.InvariantCultureIgnoreCase))
                return entry.Value;
        return null;
    }

    public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model,
                           DependencyModel dependency)
    {
        if (context == null || context.AdditionalParameters == null)
            return false;

        foreach (DictionaryEntry entry in context.AdditionalParameters)
            if (dependency.DependencyKey.Equals(entry.Key as string, StringComparison.InvariantCultureIgnoreCase))
                return true;
        return false;
    }
}

Again, as always, there’s more info on the CastleProject.org site.