この記事について
前回に引き続きVContainerの説明をしていきます。
今回はLifetimeScopeの基本的な使い方を説明します。
LifetimeScopeを使うと前回紹介したIContainerBuilder
とIObjectResolver
を簡単に扱えます。
目次ページ: VContainer入門
LifetimeScopeを試してみる
動作確認用のクラスを作成
今回もサンプルとして前回と全く同じクラスを使います。念のためそのまま載せてきます。
using UnityEngine;
using VContainer;
// 先頭に[Logger]を付けてログ出力するクラス
public sealed class Logger
{
public void Log(string message) => Debug.Log("[Logger] " + message);
}
// 足し算するだけのクラス
public sealed class Calculator
{
public int Add(int a, int b) => a + b;
}
// LoggerとCalculatorに依存するクラス
public sealed class HogeClass
{
private readonly Logger logger;
private readonly Calculator calculator;
[Inject]
public HogeClass(Logger logger, Calculator calculator)
{
this.logger = logger;
this.calculator = calculator;
}
public void LoggerTest()
{
logger.Log("LoggerTest");
}
public void CalculatorTest(int a, int b)
{
int result = calculator.Add(a, b);
logger.Log($"{a} + {b} = {result}");
}
}
LifetimeScopeを作成
これを使うLifetimeScopeは以下のようになります。
using VContainer;
using VContainer.Unity;
public sealed class TestLifetimeScope : LifetimeScope
{
protected override void Configure(IContainerBuilder builder)
{
builder.Register<Logger>(Lifetime.Singleton);
builder.Register<Calculator>(Lifetime.Singleton);
builder.Register<HogeClass>(Lifetime.Singleton);
}
}
前回、VContainerを使う流れとして次の説明をしました。
- IContainerBuilderを生成する。
- IContainerBuilderに使いたいクラスを登録する。
- IContainerBuilderからIObjectResolverを生成する。
- IObjectResolverを通して使いたいクラスを生成する。
LifetimeScope
クラスを継承すると、この1,2,3を自動的にやってくれます。
2の段階でConfigure
というメソッドを呼び出してくれるのでこれをoverrideして好きなクラスを登録します。引数に渡されたIContainerBuilder
のRegisterを呼び出してください。
LifetimeScopeを使う
LifetimeScope
はMonoBehaviour
を継承したクラスなのでGameObjectにアタッチして使います。
下の画像はTestLifetimeScopeのインスペクタです。
いくつか設定項目がありますが、ひとまずAutoRunにチェックが付いていることを確認してください。チェックが付いていればAwakeのタイミングで1~3をやってくれます。
次にこのLifetimeScopeを使うTestMonoBehaviour
クラスを作成します。
このクラスをTestlifetimeScope
とおなじGameObjecctにアタッチすれば動きます。
using UnityEngine;
using VContainer;
public sealed class TestMonoBehaviour : MonoBehaviour
{
public void Start()
{
TestLifetimeScope testLifetimeScope = GetComponent<TestLifetimeScope>();
HogeClass hogeClass = testLifetimeScope.Container.Resolve<HogeClass>();
hogeClass.CalculatorTest(2, 3); // 2 + 3 = 5 と表示される
}
}
LifetimeScopeが生成したIContainerBuilderはContainer
プロパティに入れられています。そこからHogeClassをResolveして使っているだけです。
ComponentにInjectする
先ほどの例ではLifetimeScopeのContainerプロパティに直接アクセスしていましたが、もっと便利な方法があります。
TestMonoBehaviour自体を登録して自動的にResolveしてもらいます。
まずはLifetimeScopeでTestMonoBehaviourを登録します。
using UnityEngine;
using VContainer;
using VContainer.Unity;
public sealed class TestLifetimeScope : LifetimeScope
{
// testMonoBehaviourをインスペクタで設定する
[SerializeField] private TestMonoBehaviour testMonoBehaviour;
protected override void Configure(IContainerBuilder builder)
{
builder.Register<Logger>(Lifetime.Singleton);
builder.Register<Calculator>(Lifetime.Singleton);
builder.Register<HogeClass>(Lifetime.Singleton);
// testMonoBehaviourのインスタンスを登録する
builder.RegisterComponent(testMonoBehaviour);
}
}
[SerializeField] private TestMonoBehaviour testMonoBehaviour;
とbuilder.RegisterComponent(testMonoBehaviour);
の行を追加しました。
RegisterComponent
はMonoBehaviourを登録するためのメソッドです。[Inject]属性がついたメンバが存在すればIObjectResolver
を生成した直後にそのインスタンスにInjectしてくれます。
TestMonoBehaviourもInjectできるように書き換えます。
using UnityEngine;
using VContainer;
public sealed class TestMonoBehaviour : MonoBehaviour
{
private HogeClass hogeClass;
[Inject]
public void Inject(HogeClass hogeClass)
{
this.hogeClass = hogeClass;
}
public void Start()
{
hogeClass.CalculatorTest(2, 3); // 2 + 3 = 5 と表示される
}
}
IObjectResolver
は[Inject]属性が付いたメソッドを発見して、登録されているものの中から合致するものを自動的にResolveして渡してくれます。
この形ならTestMonoBehaviour
側はどこからHogeClassが渡されてくるかを気にせずに実装できます。
まとめ
-
LifetimeScope
クラスを継承して必要なLifetimeScopeを実装します。 - LifetimeScopeはAutoRunのチェックが付いていればAwakeのタイミングで以下のことをしてくれます。
- IContainerBuilderを生成してConfigureに渡します。
- IContainerBuilderからIObjectResolverを生成してContainerプロパティに保持します。
-
RegisterComponent
でMonoBehaviourのインスタンスをわたしてInjectできます。
次回はRegisterやRegsiterComponent以外の登録用メソッドを紹介する予定です。