More Castle Windsor

In an unexpected move, I decided to go back and demonstrate the automatic injection of dependencies in the old Castle sample app from before. I did so because, well, not doing so I felt kind of missed the entire point of dependency injection.

Code Changes

There are a few initial changes to the source worth mentioning: I renamed the DataSourceFacility assembly to simply DataSource as I wished to avoid the ‘Facility’ word which has a different meaning altogether in the context of Castle Windsor.

As I hinted in the previous blog post I lifted the data access method  from the HomeController class to a dedicated data factory consumer class (cunningly name FactoryConsumer) in the DataSource assembly. To maintain an air of civility I also defined a new interface IFactoryConsumer which the FactoryConsumer class would then implement.

 

using System;
using System.Collections.Generic;

namespace DataSource
{
    public interface IFactoryConsumer
    {
        void LoadData(ref List<DataModel.Entity> lst, 
             NHibernate.ISession session);
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataModel;

namespace DataSource
{
    public class FactoryConsumer : DataSource.IFactoryConsumer
    {
        IDataFactory m_fac;

        public FactoryConsumer(IDataFactory fac) {
            m_fac = fac;
        }

        #region IFactoryConsumer Members

        void IFactoryConsumer.LoadData(ref List<Entity> lst, NHibernate.ISession session)
        {
            lst.AddRange(m_fac.GetData(session));
        }

        #endregion
    }
}

In the home controller I, perhaps not so wisely, renamed the existing data access function LoadDataFromFactory to demonstrate that it loads data directly from the IDataFactory, and created a new function LoadData that gets its data from a IFactoryConsumer.  Then I changed the caller to access both function, getting product data from the Factory Consumer, where Castle secretly and automatically figures out which factory to use, while still loading service data from the factory directly as before.

Config changes

To accomplish the above there had to be some changes to the configuration file. I specified that the Product Data factory has a ‘service’, which is, incidentally IDataFactory. Ahead of both factories I declared my factory consumer. As you can see, Castle cleverly figures out quite a few things on its own, like how to create my Factory Consumer with no more than two empty hands and, incidentally, a component just a line or two below in the web.config file that actually implements IDataFactory which is what it needs to call the constructor of the FactoryConsumer.

 

  <castle>
    <facilities>
      <facility id="loggingfacility" 
                type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" 
                loggingApi="log4net" 
                configFile="logging.config" />
    </facilities>
    <components>
      <component id="ProductLoader" 
                 type="DataSource.FactoryConsumer, DataSource"  />
      <component id="ProductData" 
                 type="DataSource.ProductInfoFactory, DataSource"
                 service="DataSource.IDataFactory, DataSource"/>
      <component id="ServiceData" 
                 type="DataSource.ServiceInfoFactory, DataSource" />
    </components> 
  </castle>

 

Output changes

When you make the above changes to the source, rebuild and ‘play’, you will notice the following changes compared to the other source:

 

That’s right. Nothing. Exactly the same output is produced.

So, what was the point of all this you ask? Well, as you can see, I could easily move the ‘service’ tag in the config file and have the web page display service info only. We have lifted the dependency control right out of our lap and left it in the hands of the guy/gal who owns the config file. There are so many implications of this; everything from enabling completely changing to different data sources or services on the fly, making partial upgrades, moving from staging to production environments dynamically and so on.

Advertisements

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