本日は VContainer の小ネタ枠です。
EnqueueParent を使ってシーンを跨いで親 LifetimeScope を設定する手順について記事に残します。
前回記事
以下の前回記事のプロジェクトを利用します。
bluebirdofoz.hatenablog.com
シーンを追加する
異なる LifetimeScope を持ったシーンを追加するサンプルを作成しました。
1つ目のシーン
・RootParentLifetimeScope.cs
using VContainer; using VContainer.Unity; namespace EnqueueParentSample { public class RootParentLifetimeScope : LifetimeScope { protected override void Configure(IContainerBuilder builder) { // HelloWorldServiceをDIコンテナに登録する builder.Register<HelloWorldService>(Lifetime.Singleton); } } }
2つ目のシーン
・GameLifetimeScope.cs
using UnityEngine; using VContainer; using VContainer.Unity; namespace EnqueueParentSample { public class GameLifetimeScope : LifetimeScope { [SerializeField] private HelloScreen helloScreen; protected override void Configure(IContainerBuilder builder) { // GamePresenterをVContainerのEntryPointに登録する builder.RegisterEntryPoint<GamePresenter>(); // HelloScreenコンポーネントをDIコンテナに登録する builder.RegisterComponent<HelloScreen>(helloScreen); } } }
GameLifetimeScope.cs は HelloWorldService を参照する必要があるので、RootParentLifetimeScope.cs の子 LifetimeScope である必要があります。
シーンの遷移処理
まずは以下の通り、普通にシーンを追加するのみの以下のスクリプトを作成しました。
1つ目のシーンが起動すると同時に LoadScene 関数が呼び出されて2つ目のシーンが追加される形で開きます。
・NextSceneLoader.cs
using UnityEngine; using UnityEngine.SceneManagement; using VContainer.Unity; namespace EnqueueParentSample { public class NextSceneLoader : MonoBehaviour { void Start() { SceneManager.LoadScene("NextEnqueueParentSample", LoadSceneMode.Additive); } } }
合わせてシーン参照のため、BuildSettingsにシーンを登録しておきます。
動作確認
この状態でシーンを再生してみます。
すると LifetimeScope はシーン間では参照できないため、以下のエラーが発生します。
VContainerException: Failed to resolve EnqueueParentSample.GamePresenter : No such registration of type: EnqueueParentSample.HelloWorldService
EnqueueParentを使ってシーンを跨いで親LifetimeScopeを設定する
次にシーンを遷移するスクリプトを以下の通り、修正しました。
・NextSceneLoader.cs
using UnityEngine; using UnityEngine.SceneManagement; using VContainer.Unity; namespace EnqueueParentSample { public class NextSceneLoader : MonoBehaviour { [SerializeField] private LifetimeScope firstSceneLifetimeScope; void Start() { LifetimeScope.EnqueueParent(firstSceneLifetimeScope); SceneManager.LoadScene("NextEnqueueParentSample", LoadSceneMode.Additive); } } }
firstSceneLifetimeScope 変数には1つ目のシーンの LifetimeScope の参照を設定します。
LifetimeScope.EnqueueParent は指定の LifetimeScope を親として登録する関数です。
このため、2つ目のシーンの LifetimeScope が1つ目の LifetimeScope で登録した HelloWorldService を参照できるようになります。
vcontainer.hadashikick.jp
動作確認
シーンを再生して確認してみます。
参照が正常に解決され、エラーが発生せずにスクリプトが正常に動作するようになりました。