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

升级Unity 5.11.10后DTO映射器循环依赖触发StackOverflow异常如何解决

问题根因

Unity 5.x 调整了依赖注入与初始化方法的执行顺序:4.x版本中会先完成当前对象的实例化、所有属性注入,再执行InjectionMethod指定的初始化方法;而5.x版本会在注入属性时立即触发依赖对象的实例化、属性注入与初始化流程,你的两个Mapper互相依赖,就会触发递归调用,最终栈溢出。

解决方案

方案1:延后初始化时机(推荐)

Mapper属于只需初始化一次的全局配置类,直接改为单例生命周期,移除注册时自动调用Init的逻辑,等所有Mapper实例化、属性注入完成后手动统一触发初始化:

  1. 修改Unity注册逻辑:
public static void RegisterTypes()
{
    // 改用单例生命周期,移除自动调用Init的配置
    Container.RegisterType<IResultMapper<Object1>, Object1DtoObject1Mapper>(new SingletonLifetimeManager());
    Container.RegisterType<IResultMapper<Object2>, Object2DtoObject2Mapper>(new SingletonLifetimeManager());
    
    // 注册完成后统一触发初始化,此时两个Mapper已完成实例化与属性注入
    Container.Resolve<Object1DtoObject1Mapper>().Init();
    Container.Resolve<Object2DtoObject2Mapper>().Init();
}

这个方案不需要修改Mapper本身的业务逻辑,适配成本最低。

方案2:用Lazy<>包装依赖实现延迟加载

如果要保留自动调用Init的逻辑,可将互相依赖的属性改为延迟加载,避免实例化阶段就触发递归解析:
两个Mapper的依赖属性修改为Lazy包装:

// Object2DtoObject2Mapper.cs中修改
[Dependency]
public Lazy<Object1DtoObject1Mapper> Object1Mapper { get; set; }

// Init方法中使用时取Value
Collection(dto => dto.property, entity => entity.property, Object1Mapper.Value);
// Object1DtoObject1Mapper.cs中修改
[Dependency]
public Lazy<Object2DtoObject2Mapper> Object2Mapper { get; set; }

// Init方法中使用时取Value
Collection(dto => dto.property, entity => entity.property, Object2Mapper.Value);

Unity原生支持Lazy<>类型的依赖注入,会自动包装实例解析逻辑,只有第一次访问Value属性时才会真正解析目标实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:24:03