Unity C# で解説する Dependency Injection (依存性の注入)
【概要】
Dependency Injection (依存性の注入)は、クラス間の結合度を低くして、テストや拡張をしやすくするための技法です。Unity の C# 開発では、小覧細なスクリプトから大規模なゲームシステムまで常に役立ちます。
【デフォルトの実装と問題点】
例: Player が GameManager に依存している情報を使いたコード
public class Player : MonoBehaviour
{
private GameManager gameManager;
void Start()
{
gameManager = FindObjectOfType<GameManager>(); // 依存関係が固定
}
void Update()
{
gameManager.DoSomething();
}
}
問題:
- Player は GameManager の実装に完全に依存している
- Unit Test でのモックなどの差し替えが困難
- 再利用性が低い
【Dependency Injection を使った改善例】
方法 1: コンストラクタ注入 (MonoBehaviour外)
public class PlayerLogic
{
private IGameManager gameManager;
public PlayerLogic(IGameManager gameManager)
{
this.gameManager = gameManager;
}
public void DoSomething()
{
gameManager.DoSomething();
}
}
方法 2: メソッド/プロパティ注入
public class Player : MonoBehaviour
{
private IGameManager gameManager;
public void Initialize(IGameManager manager)
{
this.gameManager = manager;
}
void Update()
{
gameManager?.DoSomething();
}
}
【Unityでの実務的なDI実装】
GameInstallerなクラスを作成
public class GameInstaller : MonoBehaviour
{
[SerializeField] private Player player;
[SerializeField] private GameManager gameManager;
void Awake()
{
player.Initialize(gameManager);
}
}
【ZenjectなどのDIコンテナの利用】
Zenjectを使うと、インジェクションで自動的に依存性が注入されます。
public class Player : MonoBehaviour
{
[Inject]
private IGameManager gameManager;
void Update()
{
gameManager.DoSomething();
}
}
public class GameInstaller : MonoInstaller
{
public override void InstallBindings()
{
Container.Bind<IGameManager>().To<GameManager>().AsSingle();
}
}
【まとめ】
DI手段 | 特徴 |
---|---|
手動DI | Initialize()などで手動で注入。小規模向け。 |
Zenject 等 | [Inject]などを使い自動注入。中大規模向け。 |
利点 | テスト容易、拡張性高い、再利用性が高い |
Unityでは、最初は手動でこつこつとやって、解約してきたらZenjectなどのフレームワークに移行するのが普通です。
この概念を理解することで、コードの解耐性や拡張性が大きく向上します。