【Unity】ソロだけど、Zenjectを使ってみたい。超初心者向け?
万年ソロプレイなぐーるです。よろしくお願いします。
また間が空いてしまいました。
なんていうか年末年始は問題がよく出たり、人が抜けたり人が増えたり
と運用をメインにしているとバタバタな期間だったりします。
2-3月は少し落ち着くといいなあ。(4月からはまたバタつく)
zenjectを使ってみたい
C#用のDI container。
オジサン的にはSpringとかseasorとかむかーし使ってたなぁなんて印象です。
個人的にこういうの結構好きでして、多人数開発になると「こうかはばつぐんだ!」っていう感じです。
とはいえ、個人で使う分には手に余るような部分が多く、手を出しづらいのですよね。
重い腰を上げる
まずは「zenject」で検索。
Unity3DのDIフレームワーク、Zenjectの紹介 | Aiming 開発者ブログ
ふむふむ、installerとcontextとbindかぁ。
え、bindするには必ずinstallerをアタッチしないとダメなのかな?
と思ったのだけど、公式のreadmeを見てみると、すごくシンプルでも動きそう?
やってみた手順
1. unityで適当なプロジェクトを作る
2. Asset Storeでzenjectを検索して、プロジェクトにインポートする
3. 上部メニューGameObject > Zenject > SceneContext を押下して、SceneContextを作成
4. uGUIで適当にテストするbuttonを作る
4. 以下の適当スクリプトを作る(計3つ)
DIContainerに使いまわしたいオブジェクトをBindする。
そして使いたい所でResolveするだけ。
Node.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; // DIContainerにbindして色々な所で使いたいクラス public class Node { Node(){ Debug.Log("Node class New : " + this.GetHashCode()); } public void print(string message) { Debug.Log("node print == " + message + " | hashCode == " + this.GetHashCode()); } }
Exec1.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using Zenject; public class Exec1 : MonoBehaviour { [Inject] DiContainer container; public void Bind(){ // 以下の3つのbind typeがある。 Debug.Log("bind"); //container.Bind<Node>().AsSingle(); //container.Bind<Node>().AsTransient(); container.Bind<Node>().AsCached(); } public void Resolve(){ var node = container.Resolve<Node>(); node.print("exec1"); } public void UnBind(){ Debug.Log("unbind"); container.Unbind<Node>(); } }
Exec2.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using Zenject; // 使う所その2 public class Exec2 : MonoBehaviour { [Inject] DiContainer container; public void Resolve(){ var node = container.Resolve<Node>(); node.print("exec2"); } }
5. 上で作ったbuttonにイベントを割り当てる
6. 動かしてみる
結果
最小構成で簡単にbindして使う事が出来た。
containerにbindする時以下の3つを指定できる。
これを理解しておこう。
AsSingle()
bind , unbindを繰り返してもnewは一度しか発生せず、resolveの結果は変わらなかった。
つまりunbindしてもzenject内にオブジェクトを保持していて、
再bind時にはそれが利用されているようだ。
ということはGCの対象にならず、アプリを終了するまで開放することが出来ないだろう。
AsTransient()
resolveする度にnewをしている。
そのため、毎回別のオブジェクトとして扱われる。
AsCached()
AsSingle()と挙動が似ている。unbind、再bindを行うとnewされるようだ。(newされる瞬間は最初のResolve時)
つまり、unbind時にはzenjectからも開放されているため、GCの対象になってくれる。
最も使いやすいのでは無いだろうか。迷ったらとりあえずコレで良さそう。
こんな挙動の違いを見ることが出来た。
終わりに
シンプルに使おうと思うとこんなに簡単なんですね。
個人開発でしかunityを使ったことが無いので、こういった開発補助ライブラリ
は余り使わなくてもいいのかもしれないけど、メモとして残しておく!
都内は大雪です。