Mapster多派生类层级映射 无默认构造配置方案
Mapster 抽象类继承层级映射配置方案
故障原因
你当前配置失效的核心原因是Fork方法的作用域不符合预期:Fork仅会对当前正在配置的根类型对(即ParentVM -> Parent)应用分支规则,不会将你定义的ConstructUsing构造逻辑绑定到通过Include注册的派生类型映射关系上。Mapster识别到传入对象是派生类型时,会查找对应派生类型对的配置,找不到自定义构造逻辑就会默认尝试反射调用无参构造函数,因此抛出无法实例化类型A的异常。
修正后的配置
不需要为每个子类单独编写完整映射规则,也不需要使用Fork,直接在父类映射配置上链式给派生类型对补充构造逻辑即可,普通属性的映射会自动复用父类配置的映射规则,不需要重复配置:
// 领域模型转视图模型 原有配置逻辑正确,补充缺失的方法括号即可 config.NewConfig<Parent, ParentVM>() .Include<A, AVM>() .Include<B, BVM>(); // 视图模型转领域模型 修正配置 config.NewConfig<ParentVM, Parent>() .Include<AVM, A>() .Include<BVM, B>() // 直接为派生类型对指定构造逻辑,无需Fork包裹 .ForType<AVM, A>().ConstructUsing(src => new A(src.PropertyA)) .ForType<BVM, B>().ConstructUsing(src => new B(src.PropertyB));
注意:原配置代码中所有方法调用后缺失括号,属于语法错误,实际编译时会报错,修正时需要补齐。
效果说明
配置修正后可完全满足你的需求:
- 传入父类类型的映射请求时,Mapster会自动识别入参的实际派生类型,匹配对应映射规则完成转换
- 领域类不需要添加任何无参构造函数,所有实例化走你定义的带参构造,保证领域对象始终处于有效状态
- 不需要为每个派生类单独编写重复的属性映射规则,所有公共属性(比如
Name字段)的映射自动复用父类配置
关于多Fork配置的说明
同一个映射配置上支持传入多个Fork分支,但Fork的配置仅作用于当前根类型对,不会传递到Include注册的派生类型映射,因此不适合你当前的继承映射场景。
强制要求无参构造场景的最佳实践
如果后续遇到第三方组件(ORM、序列化库等)强制要求类型提供无参构造的情况,可以将无参构造的访问级别设置为protected或private:
- Mapster默认支持反射调用非公共构造函数,不影响映射功能
- 业务层代码无法访问非公共构造函数,依然只能通过带参构造实例化领域对象,保证实例状态有效性
示例代码:
public class A : Parent { public string PropertyA { get; set;} // 仅供框架、映射工具使用的非公共无参构造,业务代码不可调用 protected A() {} public A(string propertyA) { PropertyA = propertyA; } }
内容的提问来源于stack exchange,提问作者Jester1811
相关产品推荐
相关产品推荐

