3-1) 에서 살펴보았던 종속성 맵핑 메서드 중 ConstructionMethod 부분에 대해 따로 알아보자.
이전 예제에서 4번째 줄은 실제 메서드 이름이 아닌 분류 명칭일 뿐이고,
해당 위치에 Construction Method가 필요하다고 표시한 것이다.
Container.Bind<ContractType>()
.WithId(Identifier)
.To<ResultType>()
.FromConstructionMethod() // 이것!
.AsScope()
.WithArguments(Arguments)
.OnInstantiated(InstantiatedCallback)
.When(Condition)
.(Copy|Move)Into(All|Direct)SubContainers()
.NonLazy()
.IfNotBound();
1. FromNew
- C#의 new 연산자로 생성하여 바인딩한다.
- 바인딩의 기본 설정이라 Construction Method를 명시하지 않았다면 자동으로 FromNew으로 선택된다.
Container.Bind<Foo>();
Container.Bind<Foo>().FromNew(); // 윗 줄의 코드와 같다.
2. FromInstance
- 인자로 직접 객체를 넘겨 바인딩한다.
Container.Bind<Foo>().FromInstance(new Foo());
// 타입을 생략하면 대신 BindInstance를 사용할 수도 있다.
Container.BindInstance(new Foo());
Container.BindInstance(5.13f);
Container.BindInstance("foo");
// 여러개의 인스턴스들을 넘기는 것도 가능하다.
Container.BindInstances(5.13f, "foo", new Foo());
3. FromMethod / FromMethodMultiple
- 메서드를 사용하여 바인딩한다.
Container.Bind<Foo>().FromMethod(SomeMethod);
Foo SomeMethod(InjectContext context)
{
return new Foo();
}
// 여러개의 인스턴스를 넘길 경우 IEnumerable<T> 를 사용하면 된다.
IEnumerable<Foo> GetFoos(InjectContext context)
{
return new Foo[]{ new Foo(), new Foo(), new Foo() }
}
4. FromFactory / FromIFactory
- Zenject.IFactory<T> 인터페이스를 구현하는 클래스를 만들넘겨줘서 바인딩한다.
- IFactory 인터페이스는 T를 반환하는 Create() 메서드 한개만 구현하도록 되어있다.
- FromMethod와 유사하지만 IFactory를 구현한 클래스 자체도 의존성 주입이 가능한 장점이 있다고 한다.
- FromIFactory는 좀 더 자유롭게 식을 구성 가능하다.
class FooFactory : IFactory<Foo>
{
public Foo Create()
{
return new Foo();
}
}
Container.Bind<Foo>().FromFactory<FooFactory>()
class FooFactory : ScriptableObject, IFactory<Foo>
{
public Foo Create()
{
return new Foo();
}
}
Container.Bind<Foo>().FromIFactory(x => x.To<FooFactory>()
.FromScriptableObjectResource("FooFactory"))
.AsSingle();
아래 두 코드는 결과가 같다.
Container.Bind<Foo>().FromFactory<FooFactory>().AsSingle();
Container.Bind<Foo>().FromIFactory(x => x.To<FooFactory>().AsCached()).AsSingle();
5. FromComponentInNewPrefab
- 넘겨 받은 프리팹으로 새로운 게임 오브젝트를 생성한 뒤, 주입한다.
- 프리팹이기 때문에 ResultType은 반드시 UnityEngine.MonoBehaviour 혹은 UnityEngine.Component를 구현해야 한다.
- 만족하는 타입이 여러개라면 가장 처음으로 타입이 일치하는 것을 사용한다. 때문에 최대한 구체적인 타입에 바인딩을 하자.
Container.Bind<Foo>().FromComponentInNewPrefab(somePrefab);
6. FromComponentInNewPrefabResource
- FromComponentInNewPrefab과 동일하지만 리소스 폴더의 경로를 넘겨받는다.
Container.Bind<Foo>().FromComponentInNewPrefabResource("Some/Path/Foo");
7. FromComponentsInNewPrefab / FromComponentsInNewPrefabResource
- 각각 s가 붙어 복수의 할당이 가능한 버전.
- List<ContractType> 같은 곳에 주입할 수 있다.
8. FromNewComponentOnNewGameObject / FromNewComponentOnNewPrefab
- (빈 게임 오브젝트/할당한 프리팹)를 생성하고, 이 오브젝트에 주어진 타입의 컴포넌트를 붙인다.
- ResultType은 반드시 UnityEngine.MonoBehaviour 혹은 UnityEngine.Component를 구현해야 한다.
Container.Bind<Foo>().FromNewComponentOnNewGameObject();
Container.Bind<Foo>().FromNewComponentOnNewPrefab(somePrefab);
9. FromNewComponentOnNewPrefabResource
- FromNewComponentOnNewPrefab과 동일하지만 리소스 폴더의 경로를 넘겨받는다.
Container.Bind<Foo>().FromNewComponentOnNewPrefabResource("Some/Path/Foo");
10. FromNewComponentOn
- 인자로 넘겨준 게임오브젝트에 ResultType 컴포넌트를 붙인다.
Container.Bind<Foo>().FromNewComponentOn(someGameObject);
11. FromNewComponentSibling
- 현재 transform에 ResultType 컴포넌트를 붙인다.
- 주의! 이미 컴포넌트가 있다면, 새로 생성하지않고 이미 붙어있는 컴포넌트를 리턴한다.
- RequireComponent 어트리뷰트와 비슷하게 동작한다.
Container.Bind<Foo>().FromNewComponentSibling();
12. FromComponentInHierarchy / FromComponentsInHierarchy
- 하이어라키에서 하위의 오브젝트들에서 재귀탐색하여 가장 최초로 발견되는 컴포넌트를 찾는다.
- 씬 컨텍스트라면 모든 오브젝트를 탐색하니 유니티의 FindObjectByType 함수들과 같이 성능문제가 있다.
Container.Bind<Foo>().FromComponentInHierarchy().AsSingle();
13. FromComponentSibling
- 현재 transform에 붙어있는 컴포넌트를 검색한다.
- GetComponent와 비슷하게 동작한다.
Container.Bind<Foo>().FromComponentSibling();
14. FromComponentInParents / FromComponentsInParents
- 현재 transform이나 부모 transform에 붙어있는 컴포넌트를 검색한다.
Container.Bind<Foo>().FromComponentInParents();
15. FromComponentInChildren / FromComponentsInChildren
- 현재 transform이나 자식 transform에 붙어있는 컴포넌트를 검색한다.
Container.Bind<Foo>().FromComponentInChildren();
16. FromNewComponentOnRoot
- 주어진 ResultType의 컴포넌트를 Root에 붙인다.
Container.Bind<Foo>().FromNewComponentOnRoot();
17. FromResource / FromResources
- ResultType을 리소스 폴더에서 불러온다.
- 컴포넌트 제한이 아니라 텍스쳐나, 사운드, 프리팹 등 여러 타입 등이 가능하다.
Container.Bind<Texture>().WithId("Glass").FromResource("Some/Path/Glass");
18. FromScriptableObjectResource
- 리소스 경로에 있는 ScritableObject를 바인딩한다.
- 에디터에서 SO의 값을 바꾸면 원본 값이 보존되지 않기 때문에, 원본을 보존하고 싶다면 FromNewScriptableObjectResource를 사용하자.
public class Foo : ScriptableObject
{
}
Container.Bind<Foo>().FromScriptableObjectResource("Some/Path/Foo");
19. FromNewScriptableObjectResource
- FromScriptableObjectResource과 동일하지만, 카피본을 만들어서 사용한다.
20. FromResolve / FromResolveAll
- 다른 컨테이너로부터 인스턴스를 가져온다. ( DiContainer.Resolve<ResultType>() )
- 주의! ResultType이 별도의 Bind 문에서 분리되어 바인딩 되어야 동작한다.
public interface IFoo
{
}
public interface IBar : IFoo
{
}
public class Foo : IBar
{
}
Container.Bind<IFoo>().To<IBar>().FromResolve();
Container.Bind<IBar>().To<Foo>();
21. FromResolveGetter<ObjectType> / FromResolveAllGetter<ObjectType>
- 다른 바인딩을 통해 얻은 종속성의 속성을 사용하여 인스턴스를 가져온다. ( DiContainer.Resolve<ObjectType>() )
- 주의! ObjectType이 별도의 Bind 문에서 분리되어 바인딩 되어야 동작한다.
public class Bar
{
}
public class Foo
{
public Bar GetBar()
{
return new Bar();
}
}
Container.Bind<Foo>();
Container.Bind<Bar>().FromResolveGetter<Foo>(x => x.GetBar());
22. FromSubContainerResolve / FromSubContainerResolveAll
- 하위 컨테이너들에서 ResultType을 얻는다.
- 주의! 서브 컨테이너들이 ResultType을 바인딩하고 있는 경우에만 동작한다.
- 추가적으로 다음과 같은 메서드들과 조합하여 사용한다.
ByNewPrefabMethod, ByNewPrefabInstaller, ByNewPrefabResourceMethod, ByNewPrefabResourceInstaller, ByNewGameObjectInstaller, ByNewGameObjectMethod
, ByMethod, ByInstaller, ByNewContextPrefab, ByNewContextPrefabResource,ByInstance
ByNewPrefabMethod의 예시
- 프리팹을 생성하고, 이를 사용하여 컨테이너를 초기화합니다.
Container.Bind<Foo>().FromSubContainerResolve().ByNewPrefabMethod(MyPrefab, InstallFoo);
void InstallFoo(DiContainer subContainer)
{
subContainer.Bind<Foo>();
}
'🌍 Unity 연구 > Zenject' 카테고리의 다른 글
Zenject 배우기 3-1) 바인딩 (0) | 2021.09.05 |
---|---|
Zenject 배우기 2) 주입 (0) | 2021.09.05 |
Zenject 배우기 1) 기본 소개 (1) | 2021.08.29 |