升级Unity 5.11.10后DTO映射器循环依赖触发StackOverflow异常如何解决
问题根因
Unity 5.x 调整了依赖注入与初始化方法的执行顺序:4.x版本中会先完成当前对象的实例化、所有属性注入,再执行InjectionMethod指定的初始化方法;而5.x版本会在注入属性时立即触发依赖对象的实例化、属性注入与初始化流程,你的两个Mapper互相依赖,就会触发递归调用,最终栈溢出。
解决方案
方案1:延后初始化时机(推荐)
Mapper属于只需初始化一次的全局配置类,直接改为单例生命周期,移除注册时自动调用Init的逻辑,等所有Mapper实例化、属性注入完成后手动统一触发初始化:
- 修改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
相关产品推荐
相关产品推荐

