본문 바로가기
Engine/Unity

[Zenject] Unity에서 DI Framework를 사용해보고 싶다면?

by devOat 2023. 5. 10.

Zenject ?

Unity에서 DI Pattern을 편리하게 사용하기 위해 제작된 오픈 소스 DI Framework

 

Zenject Github 링크

 

GitHub - modesttree/Zenject: Dependency Injection Framework for Unity3D

Dependency Injection Framework for Unity3D . Contribute to modesttree/Zenject development by creating an account on GitHub.

github.com

 

 

Zenject Tutorial

Zenject Tutorial

 

주입 

using Zenject;
using UnityEngine;
using System.Collections;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<string>().FromInstance("Binding Test");
        Container.Bind<Test>().AsSingle();
    }
    
public class Test
{
    public Test(string message)
    {
        Debug.Log(message);
    }
}

MonoInstaller를 상속받은 Installer class를 생성한 뒤, DI Container에 종속성을 주입해야한다.

이 과정을 Zenject에서는 Binding이라고 함!

 

 

 

이러한 종속성을 클래스에 주입하는 여러가지 방법이 있는데, 주로 사용하는 두가지 방법만 소개해보겠당

 

1. 생성자 주입 (Constructor Injection)

public class PetOwner
{
    IPet _pet;

    public Foo(IPet pet)
    {
        _pet = pet;
    }
}

 

 

2. 메소드 주입 (Method Injection)

public class PetOwner
{
    IPet _pet;
    PetSnack _petSnack;

    [Inject]
    public void Constructor(IPet pet, PetSnack petSnack)
    {
        _pet = pet;
        _petSnack = petSnack;
    }
}

MonoBehaviour일 경우 생성자를 사용할 수 없으므로, 메소드 주입을 권장한다.

메소드 주입은 다른 유형의 주입이 끝난 뒤에 호출되므로, 이미 주입된 필드나 속성을 사용하여 초기화 로직을 구성할 수 있다.

 

필드에 직접 주입하는 방식도 가능하나, 후에 Zenject를 사용하지 않는 경우가 생긴다면 헬게이트가 오픈될 수 있으므로....

생성자 / 메소드 주입을 지향하자 !

 

 

Zenject를 더 잘 활용하려면 더 많은 소스코드 분석과 프레임워크 파악이 필요하겠지만,

우선 이정도의 지식만으로도 Zenject를 이용하여 유니티에서 DI Pattern을 적용해 볼 수 있을 것이다!

 

 


사용해본 결과 주입 과정에서 오류가 생기거나 했을 때 디버깅이 쉽지 않다는 단점이 있지만...

(이 부분 때문에 처음에는 꽤 고생을 했던 것 같음...ㅎㅎ)

 

몇 번 사용해서 바인딩 과정이 익숙해지면 사실 Null 참조라던가 오류가 날 일이 거의 없기도 하고?

무엇보다도 클래스간의 종속성을 직관적으로 알아볼 수 있다는 점이 좋았다 !

 

또한 구현하다보면 어쩔 수 없이 Singleton을 남발하게 되는데,,

사실상 묘하게 모든 변수를 public으로 공개해버리게 되는 것만 같아서 불편함을 느꼈던 적이 있을 것이다.

Zenject의 [Inject] 를 이용하면 필요한 클래스에만 Parameter로 받아와서 사용할 수 있으므로 캡슐화에 유리하다.

 

다른 사람의 코드를 해석할 때도 어떤 기능을 제공하려고 만든 클래스인지 의도를 읽기도 편했음 ! 

어떤 객체를 필요로 하는지만 봐도 해당 클래스가 제공하는 기능이나 구현하려는 것이 대충 읽히니까... 

 

 

또한 게임 개발할 때 대다수의 매니저를 돈디 싱글톤으로 개발했다가

게임을 리셋해야 하는 상황에서 매니저에 남은 데이터 때문에 우회해서 다시 초기화하느라 정말 고생했던 기억이 있는데, 

이 때 젠젝트를 사용했다면 다시 재주입하면 되니까 덜 고생했겠다,, 같은 생각을 했다 

 

비록 100퍼센트 이해하고 쓴다고는 할 수 없지만,,, ?! 개인적으로는 단점보다는 장점이 더 크게 와닿았다.

유지 보수가 중요한 프로젝트를 진행해야한다면 한번 사용해보는 것을 조심스레 권장함