详解Zenject与Unity每个阶段的关系

时间:2024-03-14 08:44:21

使用了Zenject的场景在每个阶段究竟发生了什么改变,这里将进行详细的讲解,这将有助于进一步了解Zenject的工作原理。

详解Zenject与Unity每个阶段的关系
Unity Awake() 阶段:

  • SceneContext.Awake() 方法被调用。这是在运行你的场景时,默认要做的第一件事。
  • Project Context 初始化. (注意每次运行程序只发生一次,如果你之前的场景加载过程中已经完成了这一步,新的场景加载时则跳过此步骤)
  1. ProjectContext prefab上所有的的可注入MonoBehaviour都通过DiContainer.QueueForInject传递到container
  2. ProjectContext遍历通过Unity Inspector添加到其Prefab中的所有 Installers ,运行他们上面的注入,并调用每个Installer 的 InstallBindings() 。每个Installer 都会在DiContainer上调用一定数量的Bind方法。
  3. ProjectContext构造所有 non-lazy 根对象,这包括从ITickable / IInitializable或IDisposable派生的任何类,以及添加了NonLazy()绑定的那些类。
  4. 注入通过DiContainer.QueueForInject添加的所有实例
  • Scene Context 初始化
  1. 场景中所有可以注入的Monebehaviours都通过DiContainer.QueueForInject传递到Container中。
  2. SceneContext遍历通过Unity Inspector添加到它的所有Installers ,运行他们上面的注入,并调用每个Installer 的 InstallBindings() 方法。每个Installer 都会在DiContainer上调用一定数量的Bind方法。
  3. SceneContext构造所有 non-lazy 根对象,这包括从ITickable / IInitializable或IDisposable派生的任何类,以及添加了NonLazy()绑定的那些类。
  4. 注入通过DiContainer.QueueForInject添加的所有实例
  • 如果仍有依赖项无法解决,抛出 ZenjectResolveException

Unity Start() 阶段

  • 调用ProjectKernel.Start()方法。这个方法将触发 ProjectContext installers上所有 IInitializable对象(实现了IInitializable接口的对象) 的Initialize()方法。(Initialize()执行顺序参看“Update / Initialization 自定义执行顺序”)
  • 调用SceneKernel.Start()方法.这个方法将触发 SceneContext installers上所有 IInitializable对象(实现了IInitializable接口的对象) 的Initialize()方法。(Initialize()执行顺序参看“Update / Initialization 自定义执行顺序”)
  • 场景中继承了MonoBehaviour的脚本调用他们的Start()方法。

Unity Update()阶段:该顺序同样适用于LateUpdate 和 FixedUpdate

  • 调用ProjectKernel.Update() 方法。这个方法将触发 ProjectContext installers上所有 ITickable 对象(实现了ITickable 接口的对象) 的Tick()方法。(Tick() 执行顺序参看“Update / Initialization 自定义执行顺序”)
  • 调用SceneKernel.Update() 方法。这个方法将触发 SceneContext installers上所有 ITickable 对象(实现了ITickable 接口的对象) 的Tick()方法。(Tick() 执行顺序参看“Update / Initialization 自定义执行顺序”)
  • 场景中继承了MonoBehaviour的脚本调用他们的Update() 方法。

Unity scene 卸载阶段

  • GameObjectContext上所有实现了IDisposable 接口的对象调用 Dispose()方法
  • SceneContext 上所有实现了IDisposable 接口的对象调用 Dispose()方法

应用程序关闭阶段

  • ProjectContext 上所有实现了IDisposable 接口的对象调用 Dispose()方法