Unity Zenject 框架基础使用
一,Unity Zenject 框架基础使用
1,前言
前段时间做的项目中有用到 Zenject + UniTask + UniRx + Localization + GoogleSheet,后续文章中会挨个说明,本期先来介绍一下Zenject。
在Unity开发中,依赖注入(Dependency Injection, DI)是一种非常有用的设计模式,它可以帮助我们更好地管理代码的依赖关系,提高代码的可维护性和可测试性。Zenject是Unity中一个非常流行的依赖注入框架,它提供了强大的功能和灵活的配置方式。本文将详细介绍如何在Unity项目中使用Zenject,并通过一些示例代码来帮助大家更好地理解和应用这个框架。
2,安装Zenject
首先,我们需要在Unity项目中安装Zenject。可以通过以下几种方式来安装:
通过Unity Package Manager安装步骤如下:
- 1,打开Unity Editor,选择 Window -> Package Manager。
- 2,点击左上角的 + 按钮,选择 Add package from git URL…。
- 3,输入Zenject的GitHub地址:https://github.com/modesttree/Zenject.git,然后点击 Add。
- 4,通过Unity Asset Store安装:
- 5,打开Unity Editor,选择 Window -> Asset Store。搜索 Zenject,找到并导入到项目中。
3,基本使用
Zenject的核心概念是 Container 和 Binding。Container 用于管理对象的创建和生命周期,而 Binding 则用于定义对象之间的依赖关系。
3.1,创建Installer
Installer是Zenject中用于配置依赖关系的类。我们可以通过继承 MonoInstaller 或 Installer 来创建自己的Installer。
using Zenject;
public class GameInstaller : MonoInstaller
{
public override void InstallBindings()
{
// 在这里配置依赖关系
Container.Bind<IPlayer>().To<Player>().AsSingle();
Container.Bind<IGameManager>().To<GameManager>().AsSingle();
}
}
在上面的示例中,我们创建了一个 GameInstaller 类,并在 InstallBindings 方法中配置了依赖关系。Container.Bind().To().AsSingle(); 表示将 IPlayer 接口绑定到 Player 类,并且使用单例模式。
3.2,使用依赖注入
在需要使用依赖的类中,我们可以通过构造函数注入的方式来获取依赖对象。
public class GameController : MonoBehaviour
{
private IPlayer _player;
private IGameManager _gameManager;
[Inject]
public void Construct(IPlayer player, IGameManager gameManager)
{
_player = player;
_gameManager = gameManager;
}
void Start()
{
_player.Move();
_gameManager.StartGame();
}
}
在上面的示例中,我们通过 [Inject] 属性标记了 Construct 方法,表示需要通过依赖注入来获取 IPlayer 和 IGameManager 的实例。
3.3,配置场景
最后,我们需要在场景中添加Installer。可以通过以下步骤来完成:

在场景中创建一个空的GameObject,并命名为 GameInstaller。
在 GameInstaller 上添加 GameInstaller 脚本。
进阶使用
Zenject还提供了许多高级功能,如子容器、信号、工厂等。下面我们将介绍一些常用的高级功能。
3.3.1.子容器
子容器可以用于管理局部的依赖关系,特别适用于复杂的场景。
public class SubContainerInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<IEnemy>().To<Enemy>().AsTransient();
}
}
在上面的示例中,我们创建了一个 SubContainerInstaller 类,并在其中配置了 IEnemy 的依赖关系。
3.3.2. 信号
信号是一种用于解耦事件系统的机制,可以帮助我们更好地管理事件的订阅和发布。
public class GameSignals : Signal<GameSignals, string> {
}
public class SignalInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.DeclareSignal<GameSignals>();
}
}
public class SignalPublisher : MonoBehaviour
{
[Inject]
GameSignals _gameSignals;
void Start()
{
_gameSignals.Fire("Game Started");
}
}
public class SignalSubscriber : MonoBehaviour
{
[Inject]
void OnEnable(GameSignals gameSignals)
{
gameSignals += OnGameStarted;
}
void OnDisable(GameSignals gameSignals)
{
gameSignals -= OnGameStarted;
}
void OnGameStarted(string message)
{
Debug.Log(message);
}
}
在上面的示例中,我们创建了一个 GameSignals 类,并在 SignalInstaller 中声明了这个信号。然后,我们在 SignalPublisher 中发布信号,在 SignalSubscriber 中订阅信号。
3.3.3,工厂
工厂模式可以用于动态创建对象,特别适用于需要频繁创建和销毁的对象。ru
public class EnemyFactory : PlaceholderFactory<Enemy>
{
}
public class FactoryInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.BindFactory<Enemy, EnemyFactory>()
.FromComponentInNewPrefabResource("EnemyPrefab");
}
}
public class GameController : MonoBehaviour
{
[Inject]
EnemyFactory _enemyFactory;
void Start()
{
var enemy = _enemyFactory.Create();
enemy.Initialize();
}
}
在上面的示例中,我们创建了一个 EnemyFactory 类,并在 FactoryInstaller 中配置了工厂绑定。然后,我们在 GameController 中使用工厂来创建 Enemy 对象。
3.3.4,IDisposable
Zenject支持 IDisposable 接口,可以用于在对象销毁时执行一些清理操作。
public class GameManager : IGameManager, IDisposable
{
public void StartGame()
{
// 游戏开始逻辑
}
public void Dispose()
{
// 清理资源
}
}
public class GameInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<IGameManager>().To<GameManager>().AsSingle();
}
}
在上面的示例中,我们实现了 IGameManager 接口,并在 Dispose 方法中执行清理操作。Zenject会在对象销毁时自动调用 Dispose 方法。
4,注意事项
生命周期管理:Zenject提供了多种生命周期管理方式,如 AsSingle、AsTransient、AsCached 等。需要根据具体情况选择合适的生命周期管理方式。
调试:可以通过 Container.Resolve 方法来手动获取依赖对象,方便调试。
性能:在大型项目中,过多的依赖注入可能会影响性能,需要注意优化。
循环依赖:避免循环依赖,循环依赖会导致依赖注入失败。
5,总结
通过本文的介绍,对Zenject有了一个基本的了解。依赖注入是一种非常强大的设计模式,可以帮助我们更好地管理代码的依赖关系,提高代码的可维护性和可测试性。新人写作不易,谢谢支持。