Part 7 - Switching implementations
So this time we're going to look at how you can not only change configuration for a component at runtime, but actually change which component is doing the work for us... powerful stuff :)
So the "trick" here is to abstract out what features we expect our component to support from it's implementation, and stuff those into an interface... so in this case I have an idea for a simple service which lets us get the "message of the day" - so lets look at my interface:
public interface IMessageOfTheDay
{
string GetMessageOfTheDay();
}
Now we have two implementations of this service, one that lets us have a static message set via configuration:
public class StaticMessageOfTheDay : IMessageOfTheDay
{
private string _message;public string Message
{
set { _message = value; }
}public string GetMessageOfTheDay()
{
return _message;
}
}
And another, which goes to wiki quotes and grabs the quote of the day:
public class WikiQuotesMessageOfTheDay : IMessageOfTheDay
{
public string GetMessageOfTheDay()
{
WebClient client = new WebClient();
string content = client.DownloadString("http://en.wikiquote.org/wiki/Main_Page");string toFind = "
return content.Substring(start, length);
}
}
so - our program is pretty simple:
private static void Main(string[] args)
{
WindsorContainer container = new WindsorContainer(new XmlInterpreter());IMessageOfTheDay motd = container.Resolve
(); Console.WriteLine("MOTD: {0}", motd.GetMessageOfTheDay());
Console.Read();
}
And so how do we swap between implementations, well we need to introduce an additional attribute to our components configuration called "service" where we specifiy what service our component implements... in this case it will be "IMessageOfTheDay" - so heres the configuration when using the Static MOTD class:
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
service="IoC.Tutorials.Part7.IMessageOfTheDay, IoC.Tutorials.Part7"
type="IoC.Tutorials.Part7.StaticMessageOfTheDay, IoC.Tutorials.Part7">Welcome to my container tutorials
And running the program gives us:
MOTD: Welcome to my container tutorials
But we can now swap to a different component with the same service at run-time, and get a different implementation... here's how that looks:
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
service="IoC.Tutorials.Part7.IMessageOfTheDay, IoC.Tutorials.Part7"
type="IoC.Tutorials.Part7.WikiQuotesMessageOfTheDay, IoC.Tutorials.Part7" />
And now running the program gives us:
MOTD: Man is not an end but a beginning. We are at the beginning of the second week. We are children of the eighth day.
A quote from Thorton Wilder - exciting huh, this seperation between interface and implementation is what makes doing so many cool things with an Inversion of control container possible... soak up the idea.
Next time we'll take a look at getting different implementations by using their "key" - have you been wondering what the "id" attribute is for in our component definitions?? Well wonder no more.