Unity依赖注入:子容器中FromScriptableObjectResource绑定失效
Zenject子容器绑定ScriptableObject无法注入的问题
当使用Zenject的FromScriptableObjectResource在父容器绑定ModuleCameraGameConfig时,子容器内的ModuleCameraGame可以正常获取到配置;但把绑定语句移到子容器内部后,同一子容器里的ModuleCameraGame却无法获取该配置,求原因及解决办法。
正常运行的代码
public class CameraServiceInstaller : Installer<CameraServiceInstaller> { public override void InstallBindings() { Container .Bind<ServiceCamera>() .FromSubContainerResolve() .ByInstaller<CameraServiceSubContainerInstaller>() .AsSingle(); Container .Bind<ModuleCameraGameConfig>().FromScriptableObjectResource("Configs/ModuleCameraGameConfig").AsSingle(); } } internal class CameraServiceSubContainerInstaller : Installer<CameraServiceSubContainerInstaller> { public override void InstallBindings() { Container .Bind<ServiceCamera>() .AsSingle(); Container .Bind<ModuleCameraGame>().FromComponentInHierarchy().AsSingle(); } }
无法运行的代码(ModuleCameraGame无法获取配置)
public class CameraServiceInstaller : Installer<CameraServiceInstaller> { public override void InstallBindings() { Container .Bind<ServiceCamera>() .FromSubContainerResolve() .ByInstaller<CameraServiceSubContainerInstaller>() .AsSingle(); } } internal class CameraServiceSubContainerInstaller : Installer<CameraServiceSubContainerInstaller> { public override void InstallBindings() { Container .Bind<ServiceCamera>() .AsSingle(); Container .Bind<ModuleCameraGame>().FromComponentInHierarchy().AsSingle(); Container .Bind<ModuleCameraGameConfig>().FromScriptableObjectResource("Configs/ModuleCameraGameConfig").AsSingle(); } }
原因分析
核心问题出在绑定顺序和FromComponentInHierarchy的解析时机:
- 异常代码中,
ModuleCameraGame用FromComponentInHierarchy()绑定,Zenject会在绑定阶段立刻去场景中查找并初始化这个组件,此时子容器里的ModuleCameraGameConfig绑定还没执行,导致注入时找不到依赖。 - 正常代码中,父容器先完成配置绑定,子容器解析
ModuleCameraGame时会向上遍历父容器的绑定表,所以能找到对应的配置。
解决方案
方案1:调整绑定顺序
在子容器中先绑定配置,再绑定需要依赖的组件,确保注入时依赖已经存在:
internal class CameraServiceSubContainerInstaller : Installer<CameraServiceSubContainerInstaller> { public override void InstallBindings() { // 先绑定配置 Container .Bind<ModuleCameraGameConfig>().FromScriptableObjectResource("Configs/ModuleCameraGameConfig").AsSingle(); Container .Bind<ServiceCamera>() .AsSingle(); Container .Bind<ModuleCameraGame>().FromComponentInHierarchy().AsSingle(); } }
方案2:延迟组件解析时机
给FromComponentInHierarchy()加上NonLazy(),让Zenject不在绑定阶段立即查找组件,而是等到第一次被注入或手动获取时再处理,此时配置已经完成绑定:
Container .Bind<ModuleCameraGame>().FromComponentInHierarchy().AsSingle().NonLazy();
内容的提问来源于stack exchange,提问作者Ilia Lataria
相关产品推荐
相关产品推荐

