5
votes

What is the proper way to inject AutoMapper to other layers?

I read this blog post , but this code cause exception below

An exception of type 'AutoMapper.AutoMapperMappingException' occurred in AutoMapper.dll but was not handled in user code

when try mapping in service layer.

List<StudentViewModel> list2 = _mapper.Map<List<StudentViewModel>>(list);

My AutoFac configuration like below:

public static class DependencyRegistration
{
    public static void Config()
    {
        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly);


        builder.RegisterType<TypeMapFactory>().As<ITypeMapFactory>();
        builder.RegisterType<ConfigurationStore>().As<ConfigurationStore>().WithParameter("mappers", MapperRegistry.Mappers).SingleInstance();
        builder.Register((ctx, t) => ctx.Resolve<ConfigurationStore>()).As<IConfiguration>().As<IConfigurationProvider>();
        builder.RegisterType<MappingEngine>().As<IMappingEngine>();

        //...
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}
2
Did you create a map between the types that you are going to convert?Yacoub Massad
What is the exception message?Yacoub Massad
@YacoubMassad yes, I created profile classes and registered them.ramin_rp
@YacoubMassad {"Missing type map configuration or unsupported mapping.\r\n\r\nMapping types:\r\nStudent -> StudentViewModel\r\nDomainModels.Student -> ViewModels.StudentViewModel\r\n\r\nDestination path:\r\nList`1[0]\r\n\r\nSource value:\r\nSystem.Data.Entity.DynamicProxies.Student_56CF505FEBA6F48D4BC49099754F9D134C329E2A4B8BCB2B62D9E22D00950B16"}ramin_rp
Can you show the code where you create your maps?Yacoub Massad

2 Answers

3
votes

It seems that you need to use the IConfiguration object that is registered in the container to create the maps like this:

var configuration = container.Resolve<IConfiguration>();
configuration.CreateMap<Student, StudentViewModel>();

I think that you should be doing this at the start of your application.

Here is a better way (IMO) to configure things in the Config method:

public static void Config()
{
    var configuration_store = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);

    var mapping_engine = new MappingEngine(configuration_store);

    configuration_store.CreateMap<Student, StudentViewModel>();

    var builder = new ContainerBuilder();

    builder.RegisterInstance(mapping_engine).As<IMappingEngine>();

    //...
    var container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

I am assuming in the last example, that your classes need access only to IMappingEngine (and not IConfiguration), since your should already setup all mappings in the Config method (or some other configuration method at application startup).

3
votes

.netcore 3 Autofac 5.1.2 AutoMapper 9.0.0 AutoMapperProfiles -> My profile name

protected override void Load(ContainerBuilder builder)
{
    builder.RegisterType<AutoMapperProfiles>().As<Profile>();
    builder.Register(c => new MapperConfiguration(cfg =>
    {
        foreach (var profile in c.Resolve<IEnumerable<Profile>>())
        {
            cfg.AddProfile(profile);
        }
    })).AsSelf().SingleInstance();

    builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve)).As<IMapper>().InstancePerLifetimeScope();
}