以前、Zenjectを簡単に使って概要を理解するための記事を書きました。
Zenjectは非MonoBehaviourのインスタンスからテクスチャなどのAssetまでいろんなものを注入できます。
この記事ではいろんなものを依存性注入する方法をまとめます。
- 準備
- 非MonoBehaviourを注入
- MonoBehaviourを注入
- Prefabをインスタンス化してMonoBehaviourを注入
- いろんな型のAssetをResourcesから読み込んで注入
- シーン上のMonoBehaviourをInstallerを書かずに手軽に注入
- まとめ
- 関連
Unity2018.2.0
Zenject 7.3.1
準備
準備として、SceneContextにMonoInstallerを持たせておきます。
このあたりのやり方は下記の記事を参照してください。
非MonoBehaviourを注入
まずは非MonoBehaviourのクラスのインスタンスを注入してみます。
インスタンスの生成方法により次の三つの方法があります。
メソッド名 | 説明 |
---|---|
FromNew() | new によりインスタンスを生成する(デフォルト) |
FromInstance() | すでに存在するインスタンスを使う |
FromMethod() | インスタンス生成用のメソッドを使って生成 |
FromNew()
はこんな感じで使います。
何も指定しない場合はFromNewになります。
public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromNew() // new Example() によりインスタンスを生成する .AsTransient(); }
FromInstance()
はこんな感じです。
public override void InstallBindings() { var instancde = new Example(); Container .Bind<IExample>() .To<Example>() .FromInstance(instancde) // すでにあるインスタンスを使う .AsTransient(); }
FromMethod()
はこんな感じです。
public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromMethod(CreateExample) // メソッドを使って生成する .AsTransient(); } private Example CreateExample() { return new Example(); }
MonoBehaviourを注入
GameObjectにアタッチされているMonoBehaviourを注入する方法は次の通りです。
ただしPrefabをインスタンス化する場合は別の方法があるので次節で説明します。
メソッド名 | 説明 |
---|---|
FromNewComponentOnNewGameObject() | GameObjectを新規生成してコンポーネントをアタッチする |
FromComponentOn() FromNewComponentOn() |
引数のGameObjectにアタッチされたコンポーネントを使うFromComponentOn() は予めアタッチされたコンポーネントを使う(無ければ例外)FromNewComponentOn() はコンポーネントを新規でアタッチ(予めアタッチされていてももう一つアタッチする) |
FromComponentSibling() FromNewComponentSibling() |
注入対象のGameObjectにアタッチされたコンポーネントを使うFromComponentSibling() は予めアタッチされたコンポーネントを使う(無ければ例外)FromNewComponentSibling() はコンポーネントを新規でアタッチ(予めアタッチされていたらそれを使う) |
FromComponentInChildren() FromComponentInParents() FromComponentInHierarchy() FromComponentOnRoot() |
それぞれ 子/親/ヒエラルキー/Contextのルート に アタッチされているコンポーネントを使う(無ければ例外) |
FromNewComponentOnNewGameObject()
はこんな感じに使います。
注入処理が行われるときにGameObjectが新規作成されます。
public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromNewComponentOnNewGameObject() // GameObjectを新規生成してコンポーネントをアタッチする .AsTransient(); }
FromComponentOn()
やFromNewComponentOn()
はこんな感じでアタッチ対象のGameObjectを渡します。
[SerializeField] private GameObject _gameObject; public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromComponentOn(_gameObject) .AsTransient(); }
FromComponentSibling()
やFromNewComponentSibling
はこんな感じで使います。
FromNewComponent()
はすでにアタッチされていても二つ目のコンポーネントをアタッチするのに対して
FromNewComponentSibling()
はすでにアタッチされていたらそれを使うようなので注意が必要そうです。
public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromComponentSibling() .AsTransient(); }
FromComponentInChildren()
/ FromComponentInParents()
/ FromComponentInHierarchy()
/ FromComponentOnRoot()
はこんな感じに使います。
public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromComponentInChildren() .AsTransient(); }
Prefabをインスタンス化してMonoBehaviourを注入
PrefabにアタッチされたMonoBehaviourを注入する方法は次の通りです。
メソッド名 | 説明 |
---|---|
FromComponentInNewPrefab() FromNewComponentOnNewPrefab() |
引数のPrefabをインスタンス化してアタッチされたコンポーネントを注入するFromNewComponentOnNewPrefab() の場合はPrefabのインスタンスに新しくコンポーネントをアタッチする |
FromComponentInNewPrefabResource() FromNewComponentOnNewPrefabResource() |
FromComponentInNewPrefab() やFromNewComponentOnNewPrefab() と基本的に同様の挙動だが、PrefabをResourcesから読み込む |
FromComponentInNewPrefab()
やFromNewComponentOnNewPrefab()
は次のようにして使います。
引数にはPrefabを与えます。
[SerializeField] private Object _prefab; public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromComponentInNewPrefab(_prefab) .AsTransient(); }
FromComponentInNewPrefabResource()
やFromNewComponentOnNewPrefabResource()
は次のように使います。
引数にはResourcesのパスを与えます。
[SerializeField] private string _prefabResourcePath; public override void InstallBindings() { Container .Bind<IExample>() .To<Example>() .FromComponentInNewPrefabResource(_prefabResourcePath) .AsTransient(); }
いろんな型のAssetをResourcesから読み込んで注入
コンポーネントではなくTextureなどのAssetをResources.Load()
で読み込んで 注入するにはFromResource()
を使います。
[SerializeField] private string _resourcePath; public override void InstallBindings() { Container .Bind<Texture2D>() .FromResource(_resourcePath) .AsTransient(); }
ただしこれでは全てのTexture2D型に同じテクスチャが注入されてしまうので、
実際にはWithId()
を使ったりするようです。
Container
.Bind<Texture>()
.WithId("ExampleTex")
.FromResource(_resourcePath)
.AsTransient();
シーン上のMonoBehaviourをInstallerを書かずに手軽に注入
Zenject Bindingというコンポーネントを使うと、シーンに置かれたGameObjectの
MonoBehaviourを、Installerを書くことなく注入できます。
使い方は次の通りです。
こんな感じになります。
後は再生すれば依存性が解決されます。
まとめ
Zenjectにおけるいろんな依存性注入の方法を紹介しました。
依存性注入の方法はまだまだあるので、もっと詳しく知りたい方はドキュメントを参照してください。