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:
User contributions licensed under CC BY-SA 3.0