Zenject 배우기 2) 주입

 

Hellow World 예제

1. Unity 씬의 hierarchy에서 오른쪽 클릭 Zenject -> Scene Context 를 눌러서 오브젝트를 생성함.

2. 프로젝트 뷰에서 오른쪽 클릭 -> Create -> Zenject -> MonoInstaller 이름을 TestInstaller.cs로 지정함.

3. 만들어진 TestInstaller 스크립트를 씬에 추가함. (Context와 같은 오브젝트여도 되고 별도로 생성해도 된다)

4. SceneContext의 MonoInstaller에 TestInstaller를 추가함.

5. TestInstaller.cs에 아래의 코드를 붙여 넣음.

using Zenject;
using UnityEngine;
using System.Collections;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<string>().FromInstance("Hello World!");
        Container.Bind<Greeter>().AsSingle().NonLazy();
    }
}

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

6. Edit -> Zenject -> Validate Current Scene으로 씬을 점검한 뒤, Play를 눌러 씬을 실행.  

7. 콘솔에 Hellow world!가 출력되는 것을 확인.

 

SceneContext는 Zenject가 씬을 시작하기 전에 모든 종속성을 설정하는 진입점이다.

또한 'NonLazy'로 설정된 모든 종속성은 Installer가 실행된 후 자동으로 생성된다. 

위의 예제에서는 Greeter 클래스가 시작 시 생성된다.

 

 

주입

컨테이너에 종속성을 선언하는 다양한 방법이 있으며, 이러한 종속성을 클래스에 주입하는 몇 가지 방법들이 있다.

 

1. 생성자 주입 (Constructor Injection)

public class Foo
{
    IBar _bar;

    public Foo(IBar bar)
    {
        _bar = bar;
    }
}

 

2. 필드 주입 (Field Injection)

필드 주입은 생성자가 호출된 직후에 발생한다. [Inject] 애트리뷰트로 표시된 모든 필드는 컨테이너에서 값이 제공된다. 필드의 한정자는 private, public 둘 다 가능하다.

public class Foo
{
    [Inject]
    IBar _bar;
}

 

3. 속성 주입 (Property Injection)

필드 주입과 동일하게 작동하며, 필드와 동일하게 setter는 private, public 둘 다 가능하다.

public class Foo
{
    [Inject]
    public IBar Bar
    {
        get;
        private set;
    }
}

 

4. 메서드 주입 (Method Injection)

- MonoBehaviours는 생성자를 만들 수 없으니 Inject Method가 권장된다.

- 주입 메서드는 다른 유형의 주입이 끝난다음에 호출된다. 때문에 이미 주입된 필드나 속성을 사용하여 초기화 로직을 구성할 수 있다.

- 초기화 로직만 수행하려는 경우 매개변수가 없어도 된다. 하지만 일반적으로 초기화 로직을 위해 주입 메서드를 사용하는건 좋은 생각은 아니다. 대신에 IInitializable.Initialize 또는 Start() 를 사용하면 전체 초기 개체 그래프가 먼저 생성될 수 있기 때문이다.

public class Foo
{
    IBar _bar;
    Qux _qux;

    [Inject]
    public void Init(IBar bar, Qux qux)
    {
        _bar = bar;
        _qux = qux;
    }
}

 

권장사항

가장 좋은 방법은 필드/속성 주입에 비해 생성자/메서드 주입을 선호하는 것이다.

물론 필드 주입이 신기해 보이고 편해 보이긴 하지만, 추후에 DI 프레임워크 없이 코드를 재사용하기로 결정한 경우 엄청난 수정이 필요할 것이다.

 

- 생성자 주입은 종속성이 클래스 생성 시 한 번만 수행되도록 한다. 대부분의 경우 초기 종속성을 공개 속성으로 노출하고 싶진 않을 것이다. 이는 변경될 여지가 있기 때문이다.

- 생성자 주입은 클래스 간에 순환 종속성을 보장하지 않는다. 하지만 Zenject는 메서드/필드/속성 주입과 같은 다른 주입 유형을 사용할 때 순환 종속성을 허용한다.
- 생성자/메서드 주입은 다른 프로그래머가 코드를 읽을 때 클래스의 모든 종속성이 무엇인지 명확하게 한다. 단순히 메서드의 매개변수 목록만 확인하면 된다. 또한 클래스에 종속성이 많아져서 분할이 필요해질 때 작업이 손쉬워진다.

 

 

 

 

 

댓글

Designed by JB FACTORY