コンストラクタを呼び出します。特にConstruction Methodを定義しない場合デフォルトでFromNewが呼ばれます
Container.Bind<Foo>().FromNew().AsCached();
Container.Bind<Foo>().AsCached(); // FromNew()は省略できる
コンストラクタが複数あった場合、最初に引数なしコンストラクタを呼ぼうとします。見つからなかった場合引数ありコンストラクタを呼びます。
既存のインスタンスを渡してBindします。
Container.Bind<Foo>().FromInstance(new Foo());
Container.BindInstance(new Foo()); // 同じ挙動
ユニークなインスタンスを明示的に渡すので、ScopeをAsTransientにしても効果はありません。実質強制的なAsCached指定?
インスタンスの生成をメソッドに移譲できます。
private Foo GetFoo() => new Foo();
Container.Bind<Foo>().FromMethod(GetFoo).AsCached();
Container.Bind<Foo>().FromMethod(() => new Foo()).AsCached();
Container.Bind<Foo>().FromMethod(injectContext => new Foo()).AsCached();
InjectContext
はInjectに関するメタ情報が詰まったクラスですが、基本的には使うことはないと思います。
配列やリストの生成をメソッドに移譲できます。
private IEnumerable<Foo> GetFoos() => new List<Foo>();
Container.Bind<Foo>().FromMethodMultiple(GetFoos).AsCached();
Container.Bind<Foo>().FromMethodMultiple(injectContext => new List<Foo>()).AsCached();
複数形である以外は FromMethod
と同様です。
任意のIFactoryクラスで生成します。
public class Foo {
public class Factory : PlaceholderFactory<Foo> { }
}
Container.Bind<Foo>().FromFactory<Foo.Factory>();
Zenject Factoryパターンについては
カスタムファクトリで生成します。
public class Foo {
public Foo(string hoge) { }
public class Factory : IFactory<Foo> {
private string _arg;
public Factory(string arg) {
_arg = arg;
}
public Foo Create() => new Foo(_arg);
}
}
Container.Bind<Foo>().FromIFactory(x => x.To<Foo.Factory>().WithArguments("hoge")).AsCached();
FromFactory
との違いは、Factory生成の自由度です。 FromFactory
は暗黙的にFromNew()
で生成されるためFactory自体の生成方法に制限がかかりますが、こちらは自由に定義できます。引数つけてもいいしSubContainerからとってきてもよい。
公式ドキュメントだとScriptableObjectからFactoryを引っ張ったりしてます。
class FooFactory : ScriptableObject, IFactory<Foo>
{
public Foo Create()
{
// ...
return new Foo();
}
}
// ScriptableObjectから生成したFooFactoryからFooを生成してBindする
Container.Bind<Foo>().FromIFactory(x => x.To<FooFactory>().FromScriptableObjectResource("FooFactory")).AsSingle();
InstantiateしたPrefabからComponentをBindします。
Container.Bind<FooBehavior>().FromComponentInNewPrefab(fooPrefab).AsCached();
内部的にはGetComponentInChildren
で探すので、複数あった場合は先に見つかった方をBindします。
FromComponentInNewPrefabの複数版です。
Container.Bind<FooBehavior>().FromComponentsInNewPrefab(fooPrefab).AsCached();
こちらはGetComponentsInChildren
で探します。
パスからPrefabをInstantiateしてBindします。
Container.Bind<FooBehavior>().FromComponentInNewPrefabResource("some/foo").AsCached();
内部的にはResources.Load
が走ります
FromComponentInNewPrefabResourceの複数版です。
Container.Bind<FooBehavior>().FromComponentsInNewPrefabResource("some/foo").AsCached();
空のGameObjectを生成してAddComponentします。
Container.Bind<FooBehavior>().FromNewComponentOnNewGameObject().AsCached();
PrefabをInstantiateしてAddComponentします。
Container.Bind<FooBehavior>().FromNewComponentInNewPrefab(fooPrefab).AsCached();
パスからPrefabをInstantiateしてAddComponentします。
Container.Bind<FooBehavior>().FromNewComponentInNewPrefabResource("some/foo").AsCached();
パスから読み込むのでResources.Load
が呼ばれます。
既存のGameObjectにAddComponentします。
Container.Bind<FooBehavior>().FromNewComponentOn(fooGameObject);
依存しているComponentと同階層にAddComponentされる
public class BarBehavior : MonoBehavior {
[Inject]
private FooBehavior _foo;
}
Container.Bind<FooBehavior>().FromNewComponentSibling();
この場合、BarBehavior
がアタッチされているGameObjectにFooBehavior
がAddComponentされます。
この特性から、Injectされる側がComponentでないと使えません。また、複数依存しているオブジェクトがあった場合それぞれの同階層にAddComponentされます。よって強制的にAsTransient指定されるイメージです。AsSingleやAsCachedを明示的に呼んでもエラーは出ませんが適用はされません。
現在のContextと同じ階層にAddComponentされます。
Container.Bind<FooBehavior>().FromNewComponentOnRoot().AsCached();
例えばSceneContextでInstallerを呼んだ場合はSceneContextと同じ階層にFooBehaviorが作成されます。基本的にSceneContextで使うことはなく、GameObjectContext
などのSubContainerで使うのがメインになるでしょう。
Resourceディレクトリのファイルを読み込んで生成します。
Container.Bind<Texture>().FromResource("some/texture").AsCached();
Resources.Load
でロードできるファイルは全部対応してます。
ResourceディレクトリのScriptable Objectを読み込みます。
Container.Bind<FooScriptable>().FromScriptableObjectResource("some/foo").AsCached();
直接元データをBindするので、動的に値を更新するとファイルが書き換わってしまうので注意
ResourceディレクトリのScriptable Objectから読み込んでコピーしたインスタンスを生成します。
Container.Bind<FooScriptable>().FromNewScriptableObjectResource("some/foo").AsCached();
元データを書き換えたくない場合はこちらを使いましょう。
シーンのヒエラルキーを辿ってコンポーネントを探してBindします。
Container.Bind<FooBehavior>().FromComponentInHierarchy();
GetComponentOnChildren
で検索する。ParentContractがある場合親のシーンも辿ると書いてるけど検証できていない・・