
So, we have all this stuff in a configuration file... but what if we have two sets of configuration we want to swap between - perhaps one for test and one for live... well here's one way of doing it with the Windsor container.
So this is our component, we use it for demonstrating which configuration is loaded:
public class WhatConfigurationService
{
private string _configuration;
public string Configuration
{
get { return _configuration; }
set { _configuration = value; }
}
}
Now here's the applications code:
private static void Main(string[] args)
{
WindsorContainer container = new WindsorContainer(new XmlInterpreter());
WhatConfigurationService whatConfiguration = container.Resolve<WhatConfigurationService>();
Console.WriteLine("Configuration: {0}", whatConfiguration.Configuration);
Console.Read();
}
So we do this by seperating our configuration sets into different files... so we create two configuration files, called:
- container-debug.config
- container-live.config
And here's what they look like:
container-debug.config
<configuration>
<components>
<component id="whatConfig.service" type="IoC.Tutorials.Part4.WhatConfigurationService, IoC.Tutorials.Part4">
<parameters>
<Configuration>Debug</Configuration>
</parameters>
</component>
</components>
</configuration>
container-live.config
<configuration>
<components>
<component id="whatConfig.service" type="IoC.Tutorials.Part4.WhatConfigurationService, IoC.Tutorials.Part4">
<parameters>
<Configuration>Live</Configuration>
</parameters>
</component>
</components>
</configuration>
So if we've moved configuration into seperate files, how does the container know about them.... well, we use
includes... so here's our main configuration file now:
<configuration>
<configSections>
<section name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<castle>
<!--<include uri="file://container-debug.config" />-->
<include uri="file://container-live.config" />
</castle>
</configuration>
So you can see that to shift between the debug and live configurations we just swap between including one configuration and another...
And when live is uncommented, running the program gives us this output:
Configuration: LiveThere are other ways to achieve the same thing, but this is often the easiest to understand... also take careful note of that
uri attribute on the include element... you don't just have to use the
file:// scheme - you can include resources (embedded in your assemblies) or extend the resource subsystem with additional support for your own types of resources - but before you do, be sure to have a look at the list of out of the box possibilities
here.
One question that was asked about during Architecture Camp was how container configuration could be synchronized between multiple servers, and includes provide one possibility, because you can place your shared configuration on a network share, or implement your own special resource type, that could for instance get the configuration from a webservice.
Next time we'll look at introducing configuration parameters, which is another way to deal with the problems of having to switch between configs at runtime - and can make your configuration easier to read and maintain too.