Reputation: 763
Just yestarday I posted this:
Automapper - Inheritance mapper not working with type converter
Now I'm trying to do what @jimmy-bogard said in his answer, but unfortunately still with no success. Base members don't get mapped.
Jimmy said:
However, you CAN use ConstructUsing to build out the initial destination object. Or a custom AfterMap, that's also inherited. Just not ConvertUsing.
Here is my new code.
/* BaseClassConstructor.cs */
public class BaseClassConstructor {
public static BaseClass Construct(ResolutionContext context) {
if (context == null || context.IsSourceValueNull)
return null;
var src = (SourceClass)context.SourceValue;
return new BaseClass() {
CommonAttr = src.SourceAttr
};
}
}
/* AutoMapperConfig.cs */
public static class AutoMapperConfig {
public static void RegisterMappings() {
AutoMapper.Mapper.Initialize(config => {
config
.CreateMap<SourceClass, BaseClass>()
.Include<SourceClass, DerivedClass1>()
.Include<SourceClass, DerivedClass2>()
.ConstructUsing(s => BaseClassConstructor.Construct(s));
config
.CreateMap<SourceClass, DerivedClass1>()
.ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2))
.IncludeBase<SourceClass, BaseClass>();
});
}
}
Did I miss something? Am I using ConstructUsing the right way?
Any help would be appreciated.
Upvotes: 3
Views: 2196
Reputation: 101453
The way you do it now it won't work, because in ConstructUsing
you create an instance of BaseClass
, while when you map source to Derived1
class - you need an instance of Derived1
class, and BaseClass
cannot be converted to that (downcast). However you can do it like this:
public class BaseClassConstructor {
public static T Construct<T>(ResolutionContext context) where T : BaseClass, new() {
if (context == null || context.IsSourceValueNull)
return null;
var src = (SourceClass) context.SourceValue;
return new T() {
CommonAttr = src.SourceAttr
};
}
}
/* AutoMapperConfig.cs */
public static class AutoMapperConfig
{
public static void RegisterMappings()
{
AutoMapper.Mapper.Initialize(config => {
config
.CreateMap<SourceClass, BaseClass>();
config
.CreateMap<SourceClass, DerivedClass1>()
.ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2))
.IncludeBase<SourceClass, BaseClass>()
.ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass1>(ctx));
config
.CreateMap<SourceClass, DerivedClass2>()
.ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2))
.IncludeBase<SourceClass, BaseClass>()
.ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass2>(ctx));
});
}
}
Basically I changed your Construct
method to return instances of derived classes too, and then use ConstructUsing
, but not on base class mapping but on Derived
classes mappings.
Upvotes: 2