Code Elegance

Windsor Castle Factory Support

Most of us know Windsor Castle the (most?) famous IoC container. Not everybody knows that you can use Castle with some extensions (facility) useful in some circumstances.

I would like to talk about the Factory Support.

The default mode for an object registered in the configuration file to be constructed is by the new operator that calls the constructor in which, if necessary, the container inject the parameters. But sometimes we need to create an object using a factory class.

Castle support this construction mode using the Factory Support Facility that means configure it in the right way. Suppose that you need to use Windsor container to get an instance of an NHibernate Session, that, like you know, it cannot be created using the new operator but it must be constructed using a SessionFactory class.

Sometimes this SessionFactory is encapsulated in a NHibernateHelper class:

public static class NHibernateHelper { private static readonly ISessionFactory sessionFactory; static NHibernateHelper() { Configuration cfg = new Configuration(); cfg.Configure(); sessionFactory = cfg.BuildSessionFactory(); } public static ISession GetNewSession() { return sessionFactory.OpenSession(); } // ... }

This class has a static method GetNewSession that return a new instance of ISession. I want to use this class (and the GetNewSession method) to obtain the session using the IoC container and I want to inject this session in a repository:

public class UserRepository : IUserRepository { public UserRepository(ISession session) { //... } }

The only things that I need to do is to configure Castle in this way:

<castle> <facilities> <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.Microkernel" /> </facilities> <components> <component id="session" type="NHibernate.ISession, NHibernate" factoryId="sessionFactory" factoryCreate="GetNewSession" /> <component id="sessionFactory" type="NHibernateHelper, CodicePlastico.Samples" /> <component id="userRepository" service="CodicePlastico.Samples.Repositories.IUserRepository, CodicePlastico.Samples" type="CodicePlastico.Samples.UserRepository, CodicePlastico.Samples" /> </components> </castle>

The first block (facilities) add to Windsor the necessary support to use the factory facility after that there’s the components registration:

The first (session) is the object that will be created using a factory, I specified the type (ISession) and the Id of the component that works as a factory (sessionFactory) and the method (factoryCreate) that should be called for the construction of ISession (GetNewSession).

Obviously you must register the factory class (sessionFactory component) and the IUserRepository (userRepository) using the usual syntax.

What happen when I request an object of type IUserRepository?

The container sees that the concrete type is UserRepository and see that the constructor receive an instance of ISession. Then it goes to see how to build an ISession object, and see that it needs to use the GetNewSession method of NHibernateHelper.

This is a quite useful technics to use when you cannot use the constructor to build an object but still want to use an IoC container.

Technorati Tags: ,,
Posted in Emanuele DelBono | No comments

No comments yet. Be the first.

Leave a reply

Spam Protection by WP-SpamFree