0

I have a project where I have been using automapper 2.2.1. I upgraded to 4.2.1 and am completely broken. I tried to follow this by changing all references to Mapper.CreateMap<Source, Target>() to Mapper.Initialize(cfg => { cfg.CreateMap<Source, Target>()}). I'm now broken bad and I cant seem to get it done.I'm getting "System.Reflection.ReflectionTypeLoadException was unhandled by user code exception with Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information", message. What am I missing. Code looks like this:

AutomapperTypeAdapterFactory

public class AutomapperTypeAdapterFactory : ITypeAdapterFactory
{
    public AutomapperTypeAdapterFactory()
    {
        //scan all assemblies finding Automapper Profile
        var profiles = AppDomain.CurrentDomain
                                .GetAssemblies()
                                .SelectMany(a => a.GetTypes())
                                .Where(t => t.BaseType == typeof(Profile));

        Mapper.Initialize(cfg =>
        {
            foreach (var item in profiles)
            {
                if (item.FullName != "AutoMapper.SelfProfiler`2")
                    cfg.AddProfile(Activator.CreateInstance(item) as Profile);
            }
        });
    }

    public ITypeAdapter Create() => new AutomapperTypeAdapter();
}

Department Profile

public class DepartmentProfile : Profile
{
    protected override void Configure()
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<Department, DepartmentDto>();
        });
    }
}

UnityContainer

public static class Container
{
    static IUnityContainer _container = new UnityContainer();

    static Container()
    {
        var typeAdapterFactory = _container.Resolve<ITypeAdapterFactory>();
        TypeAdapterFactory.SetCurrent(typeAdapterFactory);
    }
    //other container resolutions....
}
xariez
  • 529
  • 1
  • 5
  • 17

1 Answers1

0

In projects where I've moved away from the static configuration I've defined a few mapping profiles (generally a profile per application layer):

public class MappingProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Source, Destination>();
    }
}

I then configure my IoC (SimpleInjector, in my case) to find all profiles and add them to a single, unified configuration. I then register the MapperConfiguration in my container, as well as the IMapper object created from the same:

    public void ConfigureSimpleInjector(IAppBuilder app)
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        container.RegisterAutoMapper();

        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        container.RegisterMvcIntegratedFilterProvider();

        container.Verify();

        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }


public static Container RegisterAutoMapper(this Container container)
    {
        var profiles = typeof(AutoMapperRegistry).Assembly.GetTypes().Where(t => typeof(Profile).IsAssignableFrom(t)).Select(t => (Profile)Activator.CreateInstance(t));

        var config = new MapperConfiguration(cfg =>
        {
            foreach (var profile in profiles)
            {
                cfg.AddProfile(profile);
            }
        });

        container.Register<MapperConfiguration>(() => config);
        container.Register<IMapper>(() => container.GetInstance<MapperConfiguration>().CreateMapper());

        return container;
    }
}

I can then use DI for IMapper (or you could store it statically), as well as the MapperConfiguration for use in LINQ projections.

James
  • 1,028
  • 9
  • 20
  • Is your `public static Container RegisterAutoMapper(this Container container)` contained in a class that inherits from Registry? or where does **AutoMapperRegistry** in `var profiles = typeof(AutoMapperRegistry).Assembly.GetTypes()...` from?@James – xariez Apr 18 '16 at 11:27
  • It is in a class called `AutoMapperRegistry` yes, although that class is only used to get some scope for finding `Profile` types in my application's assemblies. You could use something like this instead: `Assembly.GetExecutingAssembly().GetTypes()...` – James Apr 18 '16 at 11:32
  • I'm using unity but I cant get to think how this is translated to unity `container.Register(() => config); container.Register(() => container.GetInstance().CreateMapper());` – xariez Apr 18 '16 at 13:07
  • Not quite, that kinda veers off@James – xariez Apr 18 '16 at 16:54
  • What exactly do you mean with 1.`container.Register(() => config);` 2.`container.Register(() => container.GetInstance().CreateMapper());` @James – xariez Apr 18 '16 at 17:15