Category: Windsor

Castle Typed Factory Facility reborn

Disclaimer:

Notice that code shown here is quite new and is subject to change. If you’re reading this and it’s 2010 it’s likely that the code now is slightly different. I may come back and revisit the post if there are any changes, but don’t hold my word on it.

Pulling from the container

General rule of thumb when using IoC containers is – when you’re referencing your container in your components (anywhere outside of your bootstrapping code) you’re doing it wrong. As with all rules there are exceptions, but they are rare. Still, there are cases where you have to pull from the container somehow. What to do then? Let’s use the following artificial example:

public class MessageDispatcher

{

    public void Dispatch(IMessage message)

    {

        var handler = GetHandlerFor(message);

        handler.Handle(message);

        Destroy(handler);

    }

 

    private IMessageHandler GetHandlerFor(IMessage message)

    {

        // how to implement this...

    }

 

    private void Destroy(IMessageHandler handler)

    {

        // ... and this?

    }

}

Solution – take one – the ugly

The easiest option to implement is just to take dependency on the container.

private IKernel container;

private IMessageHandler GetHandlerFor(IMessage message)

{

    return container.Resolve<IMessageHandler>(new { name = message.Name });

}

 

private void Destroy(IMessageHandler handler)

{

    container.ReleaseComponent(handler);

}

This option seems the easiest at first. You just call the container directly. However along the way you coupled your component to the container which has whole list of disadvantages and is the wrong thing to do.

Solution – take two – the bad

Ok, so if calling the container directly is bad, we can use a layer of abstraction on top of it, right? Like Common Service Locator for example… This way we can swap the container underneath which proves the component has no dependency on the container.

Well, this is certainly a step in the right direction, but it still has a whole range of flaws. First of all – it won’t work in our scenario. Take a closer look at the code above – when we’re resolving the message handler, we’re also passing an argument in. CSL does not support passing parameters. Besides, using CSL just hides the problem instead of solving it – you’re still having a dependency on an infrastructure library in your domain component.

Solution – take three – the good

The least worst way of solving this problem is to introduce dedicated factory which will hide the container from your domain. Doing this manually (provided you want to do it right) is however a lot of tedious boring work. You have to define an interface for your factory in your domain assembly, then create an implementation in another one, then actually implement all the calls (and not only to resolve, don’t forget about cleaning up after yourself), which as you’ll soon discover is a lot of repetitious code.

public class MessageDispatcher

{

    public void Dispatch(IMessage message)

    {

        var handler = GetHandlerFor(message);

        handler.Handle(message);

        Destroy(handler);

    }

 

    private void Destroy(IMessageHandler handler)

    {

        factory.DestroyHandler(handler);

    }

 

    private IMessageHandlerFactory factory;

 

    private IMessageHandler GetHandlerFor(IMessage message)

    {

        return factory.CreateNewHandler(message.Name);

    }

}

 

public interface IMessageHandlerFactory

{

    IMessageHandler CreateNewHandler(string name);

 

    void DestroyHandler(IMessageHandler handler);

}

 

// in another assembly

public class MessageHandlerFactory : IMessageHandlerFactory

{

    private IKernel container;

    public IMessageHandler CreateNewHandler(string name)

    {

        return container.Resolve<IMessageHandler>(new { name =name });

    }

 

    public void DestroyHandler(IMessageHandler handler)

    {

        container.ReleaseComponent(handler);

    }

}

Wouldn’t it be good if someone else could do the work for you? – Meet Typed Factory Facility.

Windsor Typed Factory Facility

Typed factory is just the tool for this problem – it’s an automatically created factory, created by container, but your code is unaware of the container. It’s been around since 2005 but due to severe limitations imposed on it, and lack of development in recent years it hasn’t been widely used.

However it’s been recently retuned, with new capabilities and old limitations have been removed. It’s considerably more usable now, hence the word reborn in the title on this post. Let’s get to the code, shall we?

var container = new WindsorContainer();

container.AddFacility<TypedFactoryFacility>();

container.Register(

    // register the handler and all the other components

    Component.For<MessageDispatcher>(), // register the component with dependency on our factory

    Component.For<IMessageHandlerFactory>().AsFactory() //register the factory itself (just the interface)!

    ); // that's it, now get the dispatcher

var dispatcher = container.Resolve<MessageDispatcher>();

//start dispatching...

we register the facility with the container, than we register all the components the usual way. When we want to use an interface as a factory, we register it without any implementation (if you pass an implementation it will be ignored) and then call the AsFactory() extension method, and we’re all set.

Now the kernel will implement the factory for you based on few conventions

  • all the void methods are assumed to be used to release components passed as arguments
  • all the non-void methods are assumed to be used to resolve components from the container
  • If the factory implements IDisposable, the call to dispose will release all the transient components that were resolved via the factory.

Now, how does the factory know which service to request from the container? By default:

  • Method’s return type is used to request the component by type
  • If the method on the factory interface is called GetSOMETHING, the component called SOMETHING will be requested by name
  • All the arguments passed to the method, will be forwarded to the container with names of the method’s parameters.

This however, is just the default behavior – you can easily change it, by implementing ITypedFactoryComponentSelector and registering it with the container. Then your implementation will be picked, and used to bind factory methods and their arguments to information used by the resolve appropriate components.

Custom ITypedFactoryComponentSelector – example

For example, let’s say you don’t like the GetSOMETHING convention, and decided that if the first argument of typed factory method is a string, it should be bound to component’s name instead.

public class MySelector: ITypedFactoryComponentSelector

{

    public TypedFactoryComponent SelectComponent(MethodInfo method, Type type, object[] arguments)

    {

        string componentName = null;

        if(arguments.Length>0 && arguments[0] is string)

        {

            componentName = arguments[0].ToString();

        }

 

        //let's ignore all other arguments here for simplicity sake

        return new TypedFactoryComponent(componentName, method.ReturnType, null);

    }

}

Little bonus

One thing about this facility that blew my mind, is that the factory is not limited to resolving a single type –  with literally no effort you can use it to build a generic service locator.

public interface IGenericFactory

{

    T Create<T>();

}

 

var factory = container.Resolve<IGenericFactory>();

 

var one = factory.Create<ISomeComponent>();

var two = factory.Create<IOtherComponent>();

The code is in the trunk. It may still contain bugs and not support all scenarios, so approach with caution, and as always – any feedback is appreciated.

Technorati Tags:

Castle Windsor new feature – dynamic parameters from registration site

UPDATE:

I renamed the method from WithParameters to DynamicParameters to avoid confusion and be consistent with Parameters method which is used for static parameters.

I just committed small new feature to Castle Windsor, that I think can nicely clean up your code. It remedies the following problem:

Problem

What if you have a component that relies on a dynamically provided primitive value? Things like current request’s Uri, or DateTime.Now?

public class UsesCurrentTime

{

   UsesCurrentTime(DateTime currentTime)

   {

      Console.WriteLine("Current time is {0}”, currentTime);

   }

}

Solution – the old way

Until now you had two choices:

  • wrap the dependency in a service, like ICurrentUriProvider, or IClock and take dependency on that interface
    public class UsesCurrentTime

    {

       UsesCurrentTime(IClock currentTime)

       {

          Console.WriteLine("Current time is {0}", currentTime.Now);

       }

    }

  • in the code using that service, reference the container and pull the service yourself, instead of having it injected.
    public class Uses_UsesCurrentTime

    {

       private IKernel container;

     

       public void DoSomethingWithCurrentTime()

       {

          var service = container.Resolve<UsesCurrentTime>(new {currentTime = DateTime.Now});

          // do something with the service here

       }

    }

Neither of these approaches is ideal. The new feature I mentioned is here to save the day. It basically lets you take the best of both approaches, without paying their price. You get to pass the parameters without additional layer of indirection, and without referencing container and pulling the service manually.

Solution – the new way

To use it, we need to use a new method on the fluent registration API: DynamicParameters, like this.

kernel.Register(

    Component.For<UsesCurrentTime>()

        .LifeStyle.Transient

        .DynamicParameters((kernel, parameters) => parameters["currentTime"] = DateTime.Now));

the method takes a delegate that will be invoked when the component is being resolved, but before any actual resolution, parameter matching, appropriate constructor searching etc happens. It gives you access to two things: the container itself, and the dictionary of parameters, that were passed from the call site. You can then inspect the parameters, add new, remove them, etc.

What’s more interesting – you can use it not only for primitives. You can also dynamically override components.

kernel.Register(

    Component.For<ICustomer>()

        .ImplementedBy<CustomerImpl>()

        .Named("defaultCustomer"),

    Component.For<ICustomer>().ImplementedBy<CustomerImpl2>()

        .Named("otherCustomer")

        .Parameters(

            Parameter.ForKey("name").Eq("foo"), // static parameters, resolved at registration time

            Parameter.ForKey("address").Eq("bar st 13"),

            Parameter.ForKey("age").Eq("5")),

    Component.For<CommonImplWithDependancy>()

        .LifeStyle.Transient

        .DynamicParameters((k, d) => // dynamic parameters

        {

            var randomNumber = 2;

            if (randomNumber == 2)

            {

                d["customer"] = k.Resolve<ICustomer>("otherCustomer");

            }

        }));

 

var component = kernel.Resolve<CommonImplWithDependancy>();

Assert.IsInstanceOf<CustomerImpl2>(component.Customer);

This test will pass.

Technorati Tags:

Overriding generic component’s resolution in Castle Windsor

Few months ago, a user asked the following question on the Castle users discussion group. A friend asked me about the same thing today, so I thought I’d blog this so that’s easier to find than the discussion group thread. Anyway, here’s the question:

say I have the following types

public interface ISometype<T> {} 

public class SomeTypeImpl<T>:ISometype<T> {} 

public class SomeSpecificTypeImpl<T>:ISometype<T> where T: ISomeSpecificSpecifier {} 

public interface ISomeSpecificSpecifier { } 

Is there a way to register ISomeType<> in the container so that for the general case it uses SomeTypeImpl<> but for cases where T is ISomeSpecificSpecifier it could use SomeSpecificTypeImpl<>?

Solution take one – the explicit version

The solution may be similar to the following sketchy code.

class Program

{

    static void Main(string[] args)

    {

        var container = new WindsorContainer();

        container.Register(Component.For(typeof(ISometype<>)).ImplementedBy(typeof(SomeTypeImpl<>)),

                           Component.For(typeof(ISometype<>)).ImplementedBy(typeof(SomeSpecificTypeImpl<>))

                               .PreferredFor<ISomeSpecificSpecifier>());

        var selector = new Selector();

        container.Kernel.AddHandlerSelector(selector);

 

        var sometype = container.Resolve<ISometype<string>>();

        Debug.Assert(sometype.GetType() == typeof(SomeTypeImpl<string>));

 

        var sometype2 = container.Resolve<ISometype<Specifier>>();

        Debug.Assert(sometype2.GetType() == typeof(SomeSpecificTypeImpl<Specifier>));

    }

}

 

public static class Preferred

{

    public static ComponentRegistration<object> PreferredFor<TClosingGenericType>(this ComponentRegistration<object> registration)

    {

        return registration.ExtendedProperties(new Preference(typeof(TClosingGenericType)));

    }

}

 

internal class Preference

{

    public static readonly string Name = "PreferredForClosingType";

    public Type PreferredForClosingType { get; set; }

 

    public Preference(Type type)

    {

        this.PreferredForClosingType = type;

    }

}

 

public class Selector : IHandlerSelector

{

    public bool HasOpinionAbout(string key, Type service)

    {

        // that's about as much as we can say at this point...

        return service.IsGenericType && service.GetGenericArguments().Length == 1;

    }

 

    public IHandler SelectHandler(string key, Type service, IHandler[] handlers)

    {

        var @default = handlers.FirstOrDefault(h => MatchHandler(service, h));

        return @default ?? handlers.First();

    }

 

    private bool MatchHandler(Type service, IHandler handler)

    {

        if (handler.ComponentModel.ExtendedProperties.Contains(Preference.Name) == false)

            return false;

        var closingTypeRequired = (Type)handler.ComponentModel.ExtendedProperties[Preference.Name];

        var closingTypeActual = service.GetGenericArguments().Single();

        return closingTypeRequired.IsAssignableFrom(closingTypeActual);

    }

}

This version contains an explicit extension to the component registration API, to specify which component you prefer in which case. It also uses and IHandlerSelector implementation to do the actual work during resolution. It is possible however to not extend the API, and use the information we already have

Solution take two – the implicit version

class Program

{

    static void Main(string[] args)

    {

        var container = new WindsorContainer();

        container.Register(Component.For(typeof(ISometype<>)).ImplementedBy(typeof(SomeTypeImpl<>)),

                           Component.For(typeof(ISometype<>)).ImplementedBy(typeof(SomeSpecificTypeImpl<>)));

        var selector = new Selector();

        container.Kernel.AddHandlerSelector(selector);

 

        var sometype = container.Resolve<ISometype<string>>();

        Debug.Assert(sometype.GetType() == typeof(SomeTypeImpl<string>));

 

        var sometype2 = container.Resolve<ISometype<Specifier>>();

        Debug.Assert(sometype2.GetType() == typeof(SomeSpecificTypeImpl<Specifier>));

    }

}

 

public class Selector : IHandlerSelector

{

    public bool HasOpinionAbout(string key, Type service)

    {

        // that's about as much as we can say at this point...

        return service.IsGenericType && service.GetGenericArguments().Length == 1;

    }

 

    public IHandler SelectHandler(string key, Type service, IHandler[] handlers)

    {

        return handlers.FirstOrDefault(h => MatchHandler(service, h));

 

    }

 

    private bool MatchHandler(Type service, IHandler handler)

    {

        var closingTypeRequired = handler.ComponentModel.Implementation.GetGenericArguments()

            .Single().GetGenericParameterConstraints().SingleOrDefault();

        if (closingTypeRequired == null)

            return false;

        var closingTypeActual = service.GetGenericArguments().Single();

        return closingTypeRequired.IsAssignableFrom(closingTypeActual);

    }

}

This version relies on the information provided in component’s generic type constraints. The Registration API is not extended, and we just do a little bit more work in the selector. Is this version better? It depends. The explicit version is… well – explicit about what it does, and for which components. The implicit one works on its own and if you’re not careful you may end up chasing very strange bugs in your code. That said, if you do go for the second option, be sure to at least add some diagnostics logging to it, so that you can see what it does when you’re not watching.

Technorati Tags:

Castle Windsor lazy loading

I just committed a very cool feature to Castle Windsor/MicroKernel that adds lazy registration capabilities. By lazy registration I mean – you get a chance to register a component right at the spot when it’s about to be resolved.

This enables things like integration with external sources of components, like MEF, or WCF config files, lets you distribute your registration in time so that you don’t have to do all of it upfront and many more.

Behind all of this, is this interface:

/// <summary>

/// Provides lazy registration capabilities to the container.

/// </summary>

/// <remarks>

/// When a component is requested from a container, that has not been registered

/// container loads up all the implementers of this interface and asks them in turn

/// whethere they can provide that component, until it finds one that will.

/// </remarks>

public interface ILazyComponentLoader

{

    /// <summary>

    /// Used by container to allow the loader register component for given <paramref name="key"/> 

    /// and <paramref name="service"/> to the container at the time when it is requested

    /// </summary>

    /// <param name="key">Key of the requested component or null</param>

    /// <param name="service">Type of requested service or null</param>

    /// <returns>Registration that registers component for given key and/or service or null.</returns>

    /// <remarks>

    /// While both key and service can be null reference it is guaranteed that at least one of them will not be null.

    /// When implementer opts in to provide the requested component (by returning not-null registration) it is required

    /// to register component for requested key/service combination (when one of the elements is null, it should be ignored as well).

    /// When implementer does not want to register the requested component it nust return null.

    /// </remarks>

    IRegistration Load(string key, Type service);

}

You can now use it pretty easily, as I will show in a second. Let’s take a trivial example:

[DefaultImplementation(typeof(Implementation))]

public interface IHasDefaultImplementation

{

    void Foo();

}

 

public class Implementation : IHasDefaultImplementation

{

    public void Foo()

    {

        

    }

}

We have an interface, a class that implements it, and an attribute we put on the interface that points to its default implementation (assuming we have many). This example is completely artificial, but that’s not the point.

We still need some implementation of ILazyComponentLoader, that will work with this scenario.

public class Loader : ILazyComponentLoader

{

 

    public IRegistration Load(string key, Type service)

    {

        if (!Attribute.IsDefined(service, typeof(DefaultImplementationAttribute)))

        {

            return null;

        }

 

        var attributes = service.GetCustomAttributes(typeof(DefaultImplementationAttribute), false);

        var attribute = attributes[0] as DefaultImplementationAttribute;

        return Component.For(service).ImplementedBy(attribute.Implementation).Named(key);

    }

}

Our Loader is called by the container when a component is requested, that has not been registered in the container. We then check if type of the service requested has DefaultImplementationAttribute, and if it does we register the component with the default implementation, which then will be resolved.

To wire our loader with the container, we register it with ILazyComponentLoader service just like any other component. Yeah – no additional API to memorize!

var kernel = new DefaultKernel();

kernel.AddComponent<Loader>(typeof(ILazyComponentLoader));

That’s all we need to make this test pass:

[Test]

public void Can_Lazily_resolve_component()

{

 

    var service = kernel.Resolve("foo", typeof(IHasDefaultImplementation));

    Assert.IsNotNull(service);

    Assert.IsInstanceOf<Implementation>(service);

}

The code is available now in the trunk, and you can get latest binaries here.

Technorati Tags: