I am in the middle of moving over a large body of code to Castle Trunk which includes the new fluent interface for configuring the container. Since the project has a huge windso
I had a project where we were using Unity, and I watched a video about StructureMap and I liked the registration idea from the start.
So I created the following interface:
/// <summary>
/// An interface which must be implemented to create a configurator class for the UnityContainer.
/// </summary>
public interface IUnityContainerConfigurator
{
/// <summary>
/// This method will be called to actually configure the container.
/// </summary>
/// <param name="destination">The container to configure.</param>
void Configure(IUnityContainer destination);
}
And have assemblies offer a default Configurator class. We've also wrapped our Unity IoC using a static class so that we can call IoC.Resolve<T>
, and I just added the following functions to that wrapper:
/// <summary>
/// Configure the IoC
/// </summary>
public static class Configure
{
/// <summary>
/// Configure the IoC using by calling the supplied configurator.
/// </summary>
/// <typeparam name="TConfigurator">The configurator to use</typeparam>
public static void From<TConfigurator>() where TConfigurator : IUnityContainerConfigurator, new()
{
From(new TConfigurator());
}
/// <summary>
/// Configure the IoC using by calling the supplied configurator.
/// </summary>
/// <param name="configurationInterface">The configurator instance to use</param>
public static void From(IUnityContainerConfigurator configurationInterface)
{
configurationInterface.Configure(instance);
}
// other configuration.
}
So in the initialization form either the program or the website I'd just call:
IoC.Configure.From<BLL.DefaultMapping>();
In the BLL there is a class like this:
public class DefaultMapping:IUnityContainerConfigurator
{
public void Configure(IUnityContainer destination)
{
destionation.RegisterType<IRepository, SQLRepository>();
// and more..
}
}
The only downside is that all you're layers are coupled to the chosen IoC container.
Update: Since this answer I have posted an article on my blog containing the Unity wrapper.
Tricky questions [and I'm no IoC expert] but keep in mind that any "monolithic static function" should not be nearly as scary as the config file. You can define your own conventions for things, and try to abstract things down. I use Ninject, but for Windsor, I'd imagine it would involve making short little functions using things like Register with the AllTypesOf strategy:
kernel.Register(AllTypesOf<ISomethingProvider>.
FromAssembly(Assembly.Load("SomeAssembly")));
Don't know about the internal hierarchies exporting their own default configuration. That seems a little scary and inverted.
You could try examining the Ninject framework. Very simple, fluent interface and lightning-fast ;) No XML configuration and the API is quite simple. Highly recommended
Ninject
Take a deeper look at StructureMap 2.5. It offers several features to dramatically reduce the work to bootstrap the IOC container. It offers a convention over configuration technique (see the blog entries below)
See the following recent blog posts from Jeremy Miller (author of StructureMap)
Create your own Auto Registration Convention with StructureMap
// Example from the blog post above
var container = new Container(registry =>
{
registry.Scan(x =>
{
x.TheCallingAssembly();
x.With<DefaultConventionScanner>();
});
});
StructureMap 2.5.2 is Released