2018年11月30日金曜日

Zenject MonoBehaviourを継承しているオブジェクトを注入するときの注意点

Zenject MonoBehaviourを継承しているオブジェクトを注入するときの注意点

Zenjectを初めて触って[Inject]を使って注入しようとなんとなく動かしたらAssertが出たのでメモ

//丸写ししたコード
Container
  .Bind<Hoge>()    //Hogeが要求されたら
  .To<ConcreteHoge>();  //ConcreteHogeを注入する


表示されたアサートは以下のもの

ZenjectException: Assert hit! Error occurred while instantiating object of type 'Hoge'. Instantiator should not be used to create new mono behaviours.  Must use InstantiatePrefabForComponent, InstantiatePrefab, or InstantiateComponent

新しくMonoBehaviourを生成する形で注入することはしないでほしい。
代わりに下の関数を使ってねとのこと。

  • InstantiatePrefabForComponent関数
  • InstantiatePrefab関数
  • InstantiateComponent関数

ただ、今回はBind関数を使っているので上の関数は使えない。
公式ドキュメントのDiCOntainer.Bindに'See here'とあってそこを読んでいくと、ConstructionMethodという項目があり、これらの関数を使用すると上のアサートを解決できる。

ConstructionMethodにもいくつかのバリエーションがあり、自分はFromComponentInNewPrefab関数を利用した。引数にはプレハブを渡すようになっている。
これはプレハブに設定してあるコンポーネントを[Inject]指定されたところに注入するものだ。

実際に動かすと実行時に渡したプレハブのインスタンスが自動で生成されていて、無事目的を果たすことができた。

ConstructionMethodには
  • FromNew
  • FromInstance
  • FromMethod
  • FromMethodMultiple
  • FromFactory
  • FromIFactory
  • FromComponentInNewPrefab
  • FromComponentsInNewPrefab
  • FromComponentInNewPrefabResource
  • FromComponentsInNewPrefabResource
  • FromNewComponentOnNewGameObject
  • FromNewComponentOnNewPrefab
  • FromNewComponentOnNewPrefabResource
  • FromNewComponentOn
  • FromNewComponentSibling
  • FromComponentInHierarchy
  • FromComponentsInHierarchy
  • FromComponentSibling
  • FromComponentsSibling
  • FromComponentInParents
  • FromComponentsInParents
  • FromComponentInChildren
  • FromComponentsInChildren
  • FromNewComponentOnRoot
  • FromResource
  • FromResources
  • FromScriptableObjectResource
  • FromNewScriptableObjectResource
  • FromResolve
  • FromResolveAll
  • FromResolveGetter<ObjectType>
  • FromResolveAllGetter<ObjectType>
  • FromSubContainerResolve
  • FromSubContainerResolveAll
と様々な用途に対応している。(2018/11/30 確認) 公式ドキュメントはこちら
列挙している内に今回のケースだとFromNewComponentOnNewGameObject関数が一番いいと気が付いた。(パラメータを指定する必要があったわけではなかったので)
この関数を使うときはTo<>関数で型を指定する必要があるので注意。

Container
    .Bind<Hoge>()    //Hogeが要求されたら
    .To<ConcreteHoge>() //ConcreteHogeを注入する
    .FromNewComponentOnNewGameObject();


以上、深く調べるきっかけを与えた方へお礼申し上げます。
そのままだと気が付かないままでした。

0 件のコメント:

コメントを投稿