1
votes

I'm trying to register my AutoMapper (version 5.2.0) Profile class into my Unity container (Unity version 4.0.1), and it's giving me an exception:

Resolution of the dependency failed, type = IConsumer`1[Commands.INewUserEmailCommand]", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, AutoMapper.IConfigurationProvider, is an interface and cannot be constructed. Are you missing a type mapping?

Here's the profile class:

public class AutoMapperBootstrap : Profile
    {
        public AutoMapperBootstrap()
        {
            this.CreateMap<IUserEmailDTO, MergeUserEmailRequest>();
        }
    }

And here's the Unity registration snippet:

Profile typeMaps = new AutoMapperBootstrap();
var config = new MapperConfiguration(cfg => cfg.AddProfile(typeMaps));
container.RegisterInstance<IMapper>(config.CreateMapper(), new ContainerControlledLifetimeManager());

Then I have constructors that depend on the IMapper instance being injected which apparently Unity knows nothing about or it needs some extra IConfigurationProvider instance? What am I missing? When my code needs to invoke a service that relies on IMapper, Unity is throwing the exception above. Here's an example of a service that's using constructor injection trying to get an IMapper instance.

public class FooService : IFooService
{
  private readonly IMapper mapper;

  public Foo(IMapper mapper)
  {
    this.mapper = mapper;
  }
}
1
Should I just skip the container registration and use a static instance that has all the mappings? I'm thinking of having a static constructor initialize the my profile so that it will always be available...Andy

1 Answers

2
votes

@Andy, I think you just copy part of the error on your mapping, usually automapper gives you more details where it is failing and can give you a clue.

On the line below you are trying to register an instance of the IMapper class

container.RegisterInstance<IMapper>(config.CreateMapper(), new ContainerControlledLifetimeManager());

If you take a look on how actually the CreateMapper works you will see that it uses an IConfigurationProvider, check the automapper original code below

public class MapperConfiguration : IConfigurationProvider
{
    .....

    public IMapper CreateMapper()
    {
       return (IMapper) new Mapper((IConfigurationProvider) this);
    }

    .....
}

When automapper is trying to create an instance of the Mapper is trying to resolve as well the parameter IConfigurationProvider. On this case you never injected that parameter. Resolution: Inject an instance of that parameter and that's all

Here I will save for you an example of how I am using it

class Helper
{
    public static MapperConfiguration InitializeAutoMapper()
    {
        MapperConfiguration config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new ProfileA());
            cfg.AddProfile(new ProfileB());
        });

        return config;
    }
}

Registering on your Unity where container is an instance of IUnityContainer

var mapperConfig = Helper.InitializeAutoMapper();
var mapper = mapperConfig.CreateMapper();
container.RegisterType<IMapper, Mapper>(new InjectionConstructor(mapperConfig));
container.RegisterInstance(mapper, Activator.CreateInstance<T>());