You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Omu.ValueInjecter映射不同类型属性遇阻求助

解决Omu.ValueInjecter跨命名空间同结构类型映射问题

我之前也碰到过几乎一模一样的场景——新旧系统模块并行,大部分实体只是换了命名空间,结构完全一致,用Mapper.Map死活转不动,改默认映射也没效果。折腾了一阵后终于找到靠谱的解决办法,分享给你:

1. 先确认DefaultMap配置的正确姿势

你之前写的DefaultMap代码逻辑本身是对的,但必须确保这段配置在第一次调用Mapper.Map之前执行,且全局只配置一次。如果是ASP.NET这类项目,最好放在启动类(比如Program.cs或Global.asax)的初始化逻辑里,避免因执行顺序问题导致配置没生效。

再贴一遍标准的全局配置示例:

// 全局初始化阶段执行一次即可
Mapper.DefaultMap = (src, resType, tag) =>
{
    var res = Activator.CreateInstance(resType);
    res.InjectFrom(src);
    return res;
};

2. 直接用InjectFrom映射(更简洁的方式)

对于这种仅命名空间不同、属性结构完全一致的对象,其实可以跳过Mapper.Map,直接用InjectFrom完成转换,代码更直白:

// 示例:OldType是旧命名空间类型,NewType是新命名空间类型
var oldObj = new OldNamespace.OldType { /* 属性赋值 */ };
var newObj = new NewNamespace.NewType();
newObj.InjectFrom(oldObj);

这种方式不需要额外配置,只要两个类型的属性名、类型完全匹配,就能自动完成映射,比绕Mapper.Map更直接高效。

3. 封装通用扩展方法(批量处理更省心)

如果需要频繁处理这类跨命名空间的转换,可以封装一个通用扩展方法,避免重复写代码:

public static TTarget MapTo<TTarget>(this object source)
    where TTarget : new()
{
    var target = new TTarget();
    target.InjectFrom(source);
    return target;
}

// 使用方式超简洁
var newObj = oldObj.MapTo<NewNamespace.NewType>();

这个扩展方法可以复用在所有同结构类型的转换场景中,代码量骤减。

为什么你的DefaultMap配置没生效?

大概率是配置时机不对——如果在调用Mapper.Map之后才设置DefaultMap,映射逻辑已经被缓存,后续调用还是会用旧规则。一定要确保配置代码在第一次使用映射前执行。另外也要检查是否有其他模块的初始化代码覆盖了DefaultMap配置,导致你的设置失效。

备选方案:用CloneInjection快速克隆

如果上面的方法还是有问题,可以试试ValueInjecter自带的CloneInjection,它专门针对同结构对象的克隆/转换:

var newObj = oldObj.CloneTo<NewNamespace.NewType>();

这个方法内部基于InjectFrom实现,对于同结构类型适配性拉满。

最后提一句,你之前用JSON序列化反序列化的方式虽然能解决问题,但性能损耗确实明显,尤其是处理大量对象时,用上面的ValueInjecter原生方法性能会提升很多。

内容的提问来源于stack exchange,提问作者Keithin8a

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:56:57