如何在Zenject的Project Context工厂中解析Scene Context依赖?
解决Zenject跨容器依赖解析问题
问题原因很明确:StateFactory是在**ProjectContext(全局容器)中绑定的,它默认使用全局容器来解析依赖;而IFruitSpawner是在SceneContext(场景容器)**中绑定的,全局容器无法访问场景容器内的绑定项,所以创建GameplayState时找不到IFruitSpawner的实现。
下面是三种可行的解决方案,根据你的业务场景选择:
方案1:手动传递SceneContext容器给StateFactory
这种方式可控性最强,适合StateMachine必须放在全局的场景。
步骤:
- 修改
StateFactory,添加接收场景容器的方法/属性:
public class StateFactory { private readonly DiContainer _globalContainer; private DiContainer _currentSceneContainer; // 注入全局容器 public StateFactory(DiContainer globalContainer) { _globalContainer = globalContainer; } // 供SceneContext调用,设置当前场景的容器 public void SetCurrentSceneContainer(DiContainer sceneContainer) { _currentSceneContainer = sceneContainer; } public TState CreateState<TState>() where TState : StateBase { // 优先用场景容器解析,没有则回退到全局容器 return _currentSceneContainer != null && _currentSceneContainer.HasBinding<TState>() ? _currentSceneContainer.Instantiate<TState>() : _globalContainer.Instantiate<TState>(); } }
- 在SceneContext的Installer中,把当前容器传递给全局的
StateFactory:
public class FruitsInstaller : Installer<FruitsInstaller> { public override void InstallBindings() { Container.Bind<IFruitSpawner>().To<FruitSpawner>().AsSingle(); // 从全局容器获取StateFactory,传入当前场景容器 var stateFactory = Container.Resolve<StateFactory>(); stateFactory.SetCurrentSceneContainer(Container); } }
方案2:通过Zenject API获取当前活跃的SceneContext容器
利用Zenject内置的上下文查找机制,自动获取当前场景的容器,代码更简洁。
修改StateFactory的CreateState方法:
public class StateFactory { private readonly DiContainer _globalContainer; public StateFactory(DiContainer globalContainer) { _globalContainer = globalContainer; } public TState CreateState<TState>() where TState : StateBase { // 获取当前场景的SceneContext(确保场景已加载完成) var currentSceneCtx = SceneContext.CurrentSceneContext; if (currentSceneCtx != null && currentSceneCtx.Container.HasBinding<IFruitSpawner>()) { return currentSceneCtx.Container.Instantiate<TState>(); } return _globalContainer.Instantiate<TState>(); } }
注意:SceneContext.CurrentSceneContext仅在场景加载完成后有效,要确保调用CreateState时目标场景已经初始化完毕。
方案3:将StateMachine相关绑定移到SceneContext
如果你的StateMachine和GameplayState是和当前场景强绑定的(比如每个场景有独立的状态逻辑),直接把StateMachineInstaller移到SceneContext中,让所有依赖处于同一个容器内,从根源避免跨容器问题。
操作:
- 从ProjectContext的Installers列表中移除
StateMachineInstaller - 将
StateMachineInstaller添加到SceneContext的Installers列表中
这样StateFactory和IFruitSpawner都在同一个场景容器里,创建GameplayState时就能直接解析到依赖。
内容的提问来源于stack exchange,提问作者dest1
相关产品推荐
相关产品推荐

