Windsor style convention over configuration in StructureMap

So I was trying to get my  BDD project SpecMaker working on Mono only to find out  my usual IoC container of choice Castle Windsor does not play nice.  StructureMap I’ve heard plays nice in Mono, and I know a bunch of people that use it, so I gave it a whirl.

My original Windsor configuration looked something like this:

 var kernel = new DefaultKernel();
 kernel.Register(Component.For().ImplementedBy(factory)); //load implementation
                WithService.FirstInterface().  //regardless of naming first interface is listed as service
                Configure(c=>c.LifeStyle.Transient)); </div> </div> I changed this to the what I thought was the StructureMap equivalent:
 var container = new Container(registry =>
                registry.Scan(x =>
                    x.With(); //does NOT configure the first service interface
container.SetDefault(typeof(IReportFactory), new ConfiguredInstance(factory)); //specific implemenation
</div> </div> Ok so I ran my code and nearly none of my classes were registered only interfaces and classes that were in a pattern like ISpecFinder/SpecFinder.  Looking at SM’s site this is actually expected behavior, and I was not able to find anything that would work the same way as I was used to. I’m not personally a fan of naming interfaces exactly like class names, so after looking around a bit at my options with SM and a brief perusal of Windsor’s source, I used StructureMap’s extensibility to come up with the following:
class FirstInterfaceConvention : TypeRules,ITypeScanner
        public void Process(Type type, PluginGraph graph)
            if (!IsConcrete(type)) return;  //only works on concrete types
            var firstinterface = type.GetInterfaces().FirstOrDefault(); //grabs first interface
                graph.AddType(firstinterface, type); //registers type
                graph.AddType(type); //adds concrete types with no interfaces
    public class IoCConfig
        public virtual ISpecRunner InitializeRunner(Type factory)
            var container = new Container(x=> x.Scan(
            container.SetDefault(typeof(IReportFactory), new ConfiguredInstance(factory));

            return container.GetInstance();
    } </div> </div>

and perfecto!  Everything now works as it did before and I was happy that something that wasn’t supported out of the box was so very simple to add myself. Finally, SpecMaker now appears to be working in mono and is nearing a release for me which I will share shortly.

Discussion: Mentoring, Knowledge Transfer and Different Styles Of Learning