I recently updated a project from .net5 to .net6 and now I get a error when trying to resolve automapper(11.0.1) from DI (or instantiating it).
Register:
services.AddAutoMapper(typeof(MatchProfile).Assembly);
Instantiation:
var mapper = services.GetService<IMapper>();
Stacktrace:
System.InvalidOperationException: Sequence contains no matching element
at System.Linq.ThrowHelper.ThrowNoMatchException()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at AutoMapper.Configuration.MemberConfigurationExpression`3.Configure(TypeMap typeMap)
at AutoMapper.Configuration.MappingExpressionBase.Configure(TypeMap typeMap)
at AutoMapper.ProfileMap.BuildTypeMap(IGlobalConfiguration configurationProvider, ITypeMapConfiguration config)
at AutoMapper.ProfileMap.Register(IGlobalConfiguration configurationProvider)
at AutoMapper.MapperConfiguration.Seal()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.<>c.<AddAutoMapperClasses>b__12_2(IServiceProvider sp)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
is there a way to find out in which profile the error is located? Can I debug this in some way?
at AutoMapper.Configuration.MemberConfigurationExpression`3.Configure(TypeMap typeMap)
The error above is not really a useful tip to find the error, since the project is pretty large and I dont really want to comment out row for fow.
Created a unit test for this, which throws exactly the same error:
[TestClass]
public class MapperTests
{
[TestMethod]
public void AssertConfigIsValid()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(ReportsProfile).Assembly);
});
configuration.AssertConfigurationIsValid();
}
}
Edit:
ViewModels:
public class AnswerModel
{
public ICollection<AnswerFieldModel> Fields { get; set; }
}
public abstract class AnswerFieldModel
{
public Guid FieldId { get; set; }
public abstract object GetValue();
}
public sealed class AnswerFieldModel<TValue> : AnswerFieldModel
{
public TValue Value { get; set; }
public override object GetValue() => Value;
}
MappingProfile:
CreateMap<Domain.Entities.Reports.ValueObjects.Answer, AnswerModel>()
.ForMember(dest => dest.Fields, opt => opt.MapFrom(src => src.Fields))
.ReverseMap();
CreateMap<Domain.Entities.Reports.ValueObjects.AnswerField, AnswerFieldModel>()
.ForMember(dest => dest.FieldId, opt => opt.MapFrom(src => src.FieldId))
.Include(typeof(Domain.Entities.Reports.ValueObjects.AnswerField<>), typeof(AnswerFieldModel<>))
.ReverseMap();
CreateMap(typeof(Domain.Entities.Reports.ValueObjects.AnswerField<>), typeof(AnswerFieldModel<>))
.ForMember("Value", opt => opt.MapFrom("Value"))
.ReverseMap();
CodePudding user response:
Since the error originated in MemberConfigurationExpression.Configure()
, I have found the problem in the following mapping expression:
CreateMap(typeof(Domain.Entities.Reports.ValueObjects.AnswerField<>), typeof(AnswerFieldModel<>))
//.ForMember("Value", opt => opt.MapFrom("Value"))
.ReverseMap();
When this .ForMember("Value", opt => opt.MapFrom("Value"))
is commented out everything works as expected.
In AM 10.1.1 this didn't throw an error though.
Here is the documentation on how to map open generics.