Reputation: 2474
I am trying to unwrap a wrapped class to a flat object via AutoMapper.
I looked at similar questions such as AutoMapper c# runtime mapping depending on an object property, but I want the derived type to be mapped by AutoMapper, I do not want to return new MyFlatObject()
in my AutoMapper config.
All the properties should be mapped via the Value
child property, only IsDeleted
is relevant from the parent.
What I have so far:
The error is:
Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
=> MyObject -> MyFlatObject (Destination member list)
[TestClass]
public class AutoMappingTest
{
public interface IMyObject { }
public class DeletableWrapper
{
public bool IsDeleted { get; set; }
public IMyObject Value { get; set; }
}
public class MyObject : IMyObject
{
public bool Foo { get; set; }
}
public class MyFlatObject
{
public bool IsDeleted { get; set; }
public bool Foo { get; set; }
}
[TestMethod]
public void MappingTest()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<DeletableWrapper, MyFlatObject>().ConstructUsing((src, ctx) => ctx.Mapper.Map<MyFlatObject>(src.Value))
.ForMember(e => e.IsDeleted, opt => opt.MapFrom(s => s.IsDeleted));
cfg.CreateMap<MyObject, MyFlatObject>();
});
config.AssertConfigurationIsValid();
}
}
Upvotes: 1
Views: 261
Reputation: 51440
Note: My solution without ConstructUsing
From config.AssertConfigurationIsValid
, it complains that there is no mapping (rule) for the member IsDeleted
in the (class) mapping rule from MyObject
to MyFlatObject
.
You can apply Ignore()
as there is no mapping from the source and thus it will not complain.
For flattening, you can use IncludeMembers
.
var config = new MapperConfiguration((cfg) =>
{
cfg.CreateMap<AutoMappingTest.DeletableWrapper, AutoMappingTest.MyFlatObject>()
.ForMember(dest => dest.IsDeleted, opt => opt.MapFrom(src => src.IsDeleted))
.IncludeMembers(src => (AutoMappingTest.MyObject)src.Value);
cfg.CreateMap<AutoMappingTest.MyObject, AutoMappingTest.MyFlatObject>()
.ForMember(dest => dest.IsDeleted, opt => opt.Ignore());
});
As @Lucian's feedback, the .ForMember
can be omitted as AutoMapper will map the members automatically when the members have the same name:
cfg.CreateMap<AutoMappingTest.DeletableWrapper, AutoMappingTest.MyFlatObject>()
.IncludeMembers(src => (AutoMappingTest.MyObject)src.Value);
Upvotes: 3