views:

445

answers:

1

Jimmy Bogart has an article on using Automapper with an IoC container. He has an example using StructureMap but I am using Unity and I'm not sure how to use an InjectionConstructor properly.

Below is the code from the Article and below that is my poor attempt. Can anyone tell me how to do this properly?

public class ConfigurationRegistry : Registry
{
    public ConfigurationRegistry()
    {
        ForRequestedType<Configuration>()
            .CacheBy(InstanceScope.Singleton)
            .TheDefault.Is.OfConcreteType<Configuration>()
            .CtorDependency<IEnumerable<IObjectMapper>>().Is(expr => expr.ConstructedBy(MapperRegistry.AllMappers));

        ForRequestedType<IConfigurationProvider>()
            .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<Configuration>());

        ForRequestedType<IConfiguration>()
            .TheDefault.Is.ConstructedBy(ctx => ctx.GetInstance<Configuration>());
    }
}

My attempt:

  container.RegisterType<IConfiguration, Configuration>(new SingletonLifetime())
                    .Configure<InjectedMembers>()
                        .ConfigureInjectionFor<Configuration>(
                            new InjectionConstructor(typeof(IEnumerable<IObjectMapper>)), MapperRegistry.AllMappers);
+1  A: 

This is what I ended up doing:

       IEnumerable<IObjectMapper> allMappers = new List<IObjectMapper>() { 
            new TypeMapMapper(TypeMapObjectMapperRegistry.AllMappers()),
            new StringMapper(),
            new FlagsEnumMapper(),
            new EnumMapper(),
            new ArrayMapper(),
            new DictionaryMapper(),
            new EnumerableMapper(),
            new AssignableMapper(),
            //new TypeConverterMapper(),
            new NullableMapper(),
        };

        container.RegisterType<Configuration>(new SingletonLifetime())
                        .Configure<InjectedMembers>()
                            .ConfigureInjectionFor<Configuration>(
                                new InjectionConstructor(allMappers));

    container.RegisterType<IConfigurationProvider, Configuration>();
    container.RegisterType<IConfiguration, Configuration>();
    container.RegisterType<IMappingEngine, MappingEngine>();

This works but if someone else has a better implementation I'm all ears and this still has a bounty on it.

Robert Kozak
Use Automapper MapperRegistry.AllMappers() static method to get all the mappers rather than manually. But yeah similar setup I use in SM except for condensing the first statement
mattcodes
Well thats part of my problem. The Constructor for Configuration takes an IEnumerable<IObjectMapper> but MapperRegistry.AllMappers() static method returns a Func<IEnumerable<IObjectMapper>>
Robert Kozak
then you would do `TypeMapObjectMapperRegistry.AllMappers()()`. The key is the second set of parenthesis. It causes the delegate returned from `AllMappers` to be called and return `IEnumerable<IObjectMapper>` :)
Anderson Imes
Also... What is SingletonLifetime and why did you choose to write that, rather than use ContainerControlledLifetimeManager? Just curious.
Anderson Imes
That is just a wrapper. To me and my team it just reads better :)
Robert Kozak
"TypeMapObjectMapperRegistry.AllMappers()()" Thanks. I'll try that.
Robert Kozak
@Anderson. If you write that up in an answer in the next 30 mins you will get the bounty attached to this question.
Robert Kozak