Help us understand the problem. What is going on with this article?

【Unity】Zenjectをちょっと触ってみた

More than 3 years have passed since last update.

はじめに

Zenjectがイイらしいという情報を見かけたので軽く触ってみました。

環境

Unityのバージョンは5.3.5f1, OSはWindows10です

Zenject?

https://github.com/modesttree/zenject

Zenject is a lightweight dependency injection framework built specifically to target Unity 3D

DI (Dependency Injection, 依存性の注入) を扱うためのフレームワークだそうです。

1. とりあえず使ってみる

1. Zenjectのダウンロード

以下URLからダウンロードしてUnityProjectに入れます。
https://github.com/modesttree/Zenject/releases

AssetStoreからもダウンロードできます


筆者は Zenject-WithSampleGames.v4.5.unitypackage をダウンロードしました。

2. Hello World

公式のHelloWorldを参考に実際に動かしていきます。

  1. Hierarchyで右クリックして、Zenject -> Scene Context を選択して、SceneContextを作成 image



2. 以下のスクリプトを作成して好きなGameObjectにアタッチ。

TestInstaller.cs
using Zenject;
using UnityEngine;
using System.Collections;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.BindInstance("Hello World!");
        Container.Bind<TestRunner>().NonLazy();
    }
}

public class TestRunner
{
    public TestRunner(string message)
    {
        Debug.Log(message);
    }
}

3.SceneContextにTestInstaller付きのオブジェクトをアタッチ
image

4.Validate ( Ctrl + Shift + V )するとConsoleに以下のようなメッセージが表示されます.
image

あまり理解できていないのですが、InstallBindings()内にてクラス間の依存関係を定義しているみたいです。

2. サンプルをちょっと覗いてみた

同梱のサンプルゲームに使われているコードがどのような意味を持つのか表にまとめてみました。
各コードはInstallBindings()の中で呼んでいるものとしています。

コード 意味 エラー例  備考
Container.Bind<IF>().To<A>() インターフェースIFをクラスAが継承していることを保証する? AIFを継承していないとエラー IFの代わりにクラスBを入れても動くみたいです
Container.BindFactory<A, B>() クラスBFactory<A>に変換可能であることを保証する? BFactory<A>へ変換できないとエラー Factory<>はZenjectで提供されているクラス
Container.BindInstance<int>(x).AsSingle() int型の変数xが変わらないことを保証する? 1回目のBindInstance呼び出しと2回目のBindInstance呼び出しで異なるint値が渡されるとエラー
Container.BindAllInterfaces<A>().To<B>() クラスAが継承している全てのインターフェースをクラスBが継承していることを保証する? Aが継承するインターフェースの中にをBが継承していないものがあるとエラー

3. Injectを使ってみた

Injectもちょっと触ってみました。 DIを行うためのものらしいです

引数なしメソッドを呼ぶ

シーンを再生するとA()メソッドが実行されます.

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Hoge>().NonLazy();

    }
}

public class Hoge
{
    [Inject]
    void A()
    {
        Debug.Log("A");
    }
}

実行結果
image

引数ありメソッドを呼ぶ

WithArgumentsを使うとメソッドに引数を渡せるみたいです。

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Hoge>().WithArguments(810, 114514).NonLazy();
    }
}

public class Hoge
{
    [Inject]
    void A(int x, int y)
    {
        Debug.Log("A : x = " + x + ", y = " + y);
    }
}

実行結果
image

4. ITickableを使ってみた

ITickableを使うことで毎フレーム処理を実行するクラスを作ることができるらしいです。

実際に使ってみる

シーンを再生するとTick()メソッドが毎フレーム実行されます

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<ITickable>().To<A>().AsSingle();
    }
}

class A : ITickable
{
    public void Tick()
    {
        Debug.Log("Tick");
    }
}

シーンを再生すると以下のようなLogが出力されます。
image

5. IInitializableを使ってみた

開始時にInitialize()メソッドを実行させるためのインターフェースらしいです

実際に使ってみる

シーンを再生するとInitialize()メソッドが1度実行されます

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<IInitializable>().To<A>();
    }
}

class A : IInitializable
{
    public void Initialize()
    {
        Debug.Log("Initialize");
    }
}

IInitializableをInjectで代用する

以下のように書くことでも同様のことができるみたいです

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<A>().NonLazy();
    }
}

class A
{
    [Inject]
    public void Initialize()
    {
        Debug.Log("Initialize");
    }
}

参考URL

GitHub - modesttree/Zenject
https://github.com/modesttree/zenject

アセットストア - Zenject Dependency Injection IOC
https://www.assetstore.unity3d.com/jp/#!/content/17758

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした