AutoMapper Duplicate Type Map Configuration Exception

0

I'm trying to use AutoMapper to map models to entities. Currently I'm stuck with an exception when validating the configuration with configuration.AssertConfigurationIsValid(); which I can't seem to wrap my head around. The application seems to work fine if I comment out the line.

Stack trace:

AutoMapper.DuplicateTypeMapConfigurationException
  HResult=0x80131500
  Message=The following type maps were found in multiple profiles:
Application.Unions.Commands.UpdateUnion.UpdateUnionCommand to Domain.Entities.Union defined in profiles:
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
Application.Members.Commands.UpdateMember.UpdateMemberCommand to Domain.Entities.Member defined in profiles:
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
AutoMapper.Configuration.MapperConfigurationExpression
This can cause configuration collisions and inconsistent mapping.
Consolidate the CreateMap calls into one profile, or set the root Advanced.AllowAdditiveTypeMapCreation configuration value to 'true'.

  Source=AutoMapper
  StackTrace:
   at AutoMapper.MapperConfigurationExpressionValidator.AssertConfigurationExpressionIsValid()
   at AutoMapper.MapperConfiguration.AssertConfigurationIsValid()
   at Application.Common.Mappings.AutoMapperConfig.Configure() in C:\Users\Baha\source\repos\Projextx\src\Application\Common\Mappings\AutoMapperConfig.cs:line 18
   at Projextx.Application.DependencyInjection.AddApplication(IServiceCollection services) in C:\Users\Baha\source\repos\Projextx\src\Application\DependencyInjection.cs:line 14
   at Web.Startup.ConfigureServices(IServiceCollection services) in C:\Users\Baha\source\repos\Projextx\src\Web\Startup.cs:line 48
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.InvokeCore(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass9_0.<Invoke>g__Startup|0(IServiceCollection serviceCollection)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.Invoke(Object instance, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.ConfigureServicesBuilder.<>c__DisplayClass8_0.<Build>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.UseStartup(Type startupType, HostBuilderContext context, IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass12_0.<UseStartup>b__0(HostBuilderContext context, IServiceCollection services)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Web.Program.<Main>d__0.MoveNext() in C:\Users\Baha\source\repos\Projextx\src\Web\Program.cs:line 22

Here is how I register AutoMapper in Startup.

var mappingConfig = new AutoMapperConfig().Configure();
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);

And I use it as follows when mapping, IHaveCustomMappings.

public class UpdateUnionCommand : IRequest<UpdateUnionCommandVm>, IHaveCustomMappings
{
    public AddressDto Address { get; set; } = new AddressDto();
    public string PhoneNumber { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string VAT { get; set; } = string.Empty;

    public void CreateMappings(IMapperConfigurationExpression? configuration)
    {
        configuration?.CreateMap<UpdateUnionCommand, Union>()
            .ForMember(dest => dest.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
            .ForMember(dest => dest.ValueAddedTaxId, opt => opt.MapFrom(src => src.VAT))
            .ForAllMembers(options => options.Condition((src, dest, srcMember) => srcMember != null));
    }
}

The above example would be one model among multiple which could "map" differently to e.g. the Union entity. I suppose this is what causes the error but how should this be handled from an AutoMapper perspective?

The AutoMapperConfig is as follows:

public class AutoMapperConfig
{
    public static IMapperConfigurationExpression? MapperConfigurationExpression;

    public MapperConfiguration Configure()
    {
        var configuration = new MapperConfiguration(config =>
        {
            MapperConfigurationExpression = config;
            config.AddMaps(Assembly.GetExecutingAssembly());
        });

        configuration.AssertConfigurationIsValid();

        return configuration;
    }
}

Lastly the profile is setup up as:

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        var types = Assembly.GetExecutingAssembly().GetExportedTypes();
        
        var maps = (from t in types
            from i in t.GetInterfaces()
            where typeof(IHaveCustomMappings).IsAssignableFrom(t)
                    && !t.IsAbstract
                    && !t.IsInterface
            select Activator.CreateInstance(t) as IHaveCustomMappings).ToArray();

        if (maps != null)
        {
            foreach (var map in maps)
            {
                map?.CreateMappings(AutoMapperConfig.MapperConfigurationExpression);
            }
        }
    }
}

Details:

  • AutoMapper version: 9.0.0
  • .NET Core version: 3.1
c#
automapper
asked on Stack Overflow Oct 17, 2020 by brk

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0