Thursday, January 7, 2016

Lazy Loading using Windsor Castle

If you are not using Castle Windor and you want to do lazy loading of the myRepository you could write some code like the following.

      
public class MyClass
{
        private IRepository myRepository;
       
        public IRepository MyRepository
        {
            get
            {

                if (myRepository == null)
                {
                    myRepository = new Repository();
                }
                return myRepository;
            }
        }

}

The is quite repetitive code and hard codes the dependency and creation of the Repository object. The  Factory pattern could be used to abstract its creation to remove this dependency, but again writing a proper Factory without Castle Windsor is a tedious task. Check out the previous link for details on this.

With Castle Windsor this is trivial.

public Lazy MyRepository { get; set; }

You will need to turn on lazy loading. This is done in your Installer class.

    public class MyInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(

                Component.For()
                         .ImplementedBy().LifestyleTransient()

                Component.For()
                         .ImplementedBy()
                );
           
        }
    }


There is a slight difference in how you use the Property now though.

Instead of something like this as you would do in our first:

MyClass obj = new MyClass();
obj.MyRepository.SomeMethod();

Using the Castle Windsor code we need to call .Value to trigger the creation and dependency injection (lazy loading).

MyClass obj = new MyClass();
obj.MyRepository.Value.SomeMethod();

The best part about this solution is that it required very little work to implement, and IRepository and Repository are mapped in the Installer where they should be, not in the classes themselves. We also aren't calling Resolve or interacting with the IoC container anywhere except as recommended (see Three Calls Pattern).

Some technical ideas are based on discussions here.