3

就在昨天,我发布了这个:

Automapper - 继承映射器不适用于类型转换器

现在我正在尝试做@jimmy-bogard 在他的回答中所说的,但不幸的是仍然没有成功。基本成员不会被映射。

吉米说:

但是,您可以使用 ConstructUsing 构建初始目标对象。或自定义 AfterMap,这也是继承的。只是没有转换使用。

这是我的新代码。

/* 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>();
        });
    }
}

我错过了什么?我是否以正确的方式使用 ConstructUsing?

任何帮助,将不胜感激。

4

1 回答 1

2

您现在执行此操作的方式将不起作用,因为在ConstructUsing您创建 的实例时BaseClass,当您将源映射到Derived1类时 - 您需要一个Derived1类的实例,并且BaseClass无法转换为该实例(向下转换)。但是,您可以这样做:

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));
        });
    }
}

基本上,我也更改了您的Construct方法以返回派生类的实例,然后使用ConstructUsing,但不是在基类映射上而是在Derived类映射上。

于 2016-05-26T20:41:36.050 回答