びぼうろくってみんなやってる

みんなやってるからぼくもやる

Zenject めも

  • 以下公式より、Google翻訳を添えて

  • DiContainer.Bind

    • すべての依存性注入フレームワークは、最終的に型をインスタンスにバインドするためのフレームワークに過ぎません。
    • Zenjectでは、依存関係のマッピングは、コンテナと呼ばれるものにバインディングを追加することによって行われます。
    • コンテナは、特定のオブジェクトのすべての依存関係を再帰的に解決することによって、アプリケーション内のすべてのオブジェクトインスタンスを作成する方法を「認識」する必要があります。
    • コンテナは、指定された型のインスタンスを作成するように要求されると、C#reflectionを使用してコンストラクタ引数のリスト、および[Inject]属性でマークされたすべてのフィールド/プロパティを検索します。次に、コンストラクターを呼び出して新しいインスタンスを作成するために必要なこれらの依存関係のそれぞれを解決しようとします。
    • したがって、各Zenjectアプリケーションは、バインドコマンドを介して行われるこれらの依存関係のそれぞれの解決方法をコンテナに伝えなければなりません。たとえば、次のクラスを指定します。
  • DiContainer.Resolve

へぇ〜

  • いきなり全部理解するのも全部使うのもそれを広めるのも全部無理。

    • BindしてResolveしたりしなかったりしてInjectすると便利。という理解でいく。
  • Bindする側

  • MonoInstallerを継承してContainer.Bind<>();
  • PrefabもScene上のオブジェクトもクラスもインターフェースもファクトリーもBindできるしなんならIDもつけられる。
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    [SerializeField] GameObject testObject;
    [SerializeField] TestBehaviour testBehaviour;
    [SerializeField] TextAsset textAssetA;
    [SerializeField] TextAsset textAssetB;

    public override void InstallBindings()
    {
        Container.Bind<GameObject>().FromInstance(testObject).AsCached();

        Container.Bind<TestBehaviour>().FromComponentInNewPrefab(testBehaviour).AsSingle();

        Container.Bind<TextAsset>().WithId("TextAssetA").FromInstance(textAssetA).AsTransient();
        Container.Bind<TextAsset>().WithId("TextAssetB").FromInstance(textAssetB).AsTransient();

        Container.BindInterfacesAndSelfTo<TestClass>().AsSingle();
        Container.BindFactory<TestClass, TestClassFactory>();
    }

}
  • 使う側
    • [Inject] したらいい感じに使える
    • Id付きでInjectもできる。
    • DiContainerもInjectできるので好きなときにInjectしたりUnBindしたりできる。
using Zenject;

public class TestInjecter
{
    [Inject] GameObject testObject;
    [Inject] TestBehaviour testBehaviour;
    [Inject(Id = "TextAssetA")] TextAsset textAssetA;
    [Inject(Id = "TextAssetB")] TextAsset textAssetB;

    [Inject] ITestClass testClass;
    [Inject] TestClassFactory testClassFactory;

    [Inject] DiContainer container;

    public TestInjecter()
    {
        var test = testClassFactory.Create();
        Debug.Log("Number: " + test.Number + ", Name:" + test.Name);

        container.Bind<ITestClass>();

        container.Unbind<TestClassFactory>();
    }
}
  • 以下特に意味なし
public interface ITestClass
{
    int Number { get; }
    string Name { get; }
}

public class TestClass : ITestClass
{
    public int Number { get; private set; }
    public string Name { get; private set; }

    public TestClass()
    {
        Number = 0;
        Name = "たかし";

    }
}

public class TestBehaviour : MonoBehaviour
{

}

public class TestClassFactory : Factory<TestClass>
{

}