IInjected
IInjected는 필수 의존성 주입이 성공으로 끝난 뒤 한 번 실행할 후처리를 붙일 때 씁니다. 시그니처는 다음과 같습니다.
public interface IInjected
{
void OnInjected();
}
추후 IL 영역으로 추출하여, 인터페이스 상속 없이 사용하게끔 디자인을 고려하고 있습니다.
MonoBehaviour (TryInjectTarget)
ObjectInstaller.TryInjectTarget은 [SceneInject] → [GlobalInject] 순으로 필드를 채웁니다.
-
success == true일 때만OnInjected()가 호출됩니다.
여기서 성공이란,Optional == false인 필드는 모두 해결된 상태를 말합니다.info선택(
Optional) 필드는 비어 있어도 성공으로 간주됩니다. -
isReinjection == true(풀에서 다시 꺼내는 경로)일 때는OnInjected는 호출되지 않습니다.
풀용 콜백은IPoolInjectionTarget.OnPoolGet를 사용합니다.
public partial class PlayerHud : MonoBehaviour, IInjected
{
[SceneInject] private IWaveModel _waves;
[GlobalInject(Optional = true)] private IDebugOverlay _debug;
public void OnInjected() //매우 강력한 펑션
{
// 필수 필드(_waves 등)는 이미 채워진 뒤
_waves.Changed += Refresh;
Refresh();
}
}
순수 C# / ScriptableObject (Create<T>())
IScope.Create<T>()는 내부에서 생성자 주입 → 씬 필드 → 전역 필드까지 끝낸 뒤,
InjectFields 안에서 IInjected 여부를 판단합니다.
-
필드 단계에서 필수 필드 미해결이 있으면
success가 false가 되어OnInjected는 건너뜁니다.
이 경우에도 이후onCreated(틱 등록) 는 별도로 호출되므로, “주입 완료”와 “틱 등록”이 항상 같이 오는 것은 아닙니다. -
OnInjected가 호출된 뒤, 같은Create호출에서RegisterTickables(틱·IScopeDestroyable등록) 가 이어집니다.
public partial class SessionState : IInjected
{
[InjectConstructor]
public SessionState([GlobalInject] ITimeService time) { }
[SceneInject] private IPlayerRoster _roster;
public void OnInjected()
{
// ctor + 모든 필수 Global/Scene 필드 반영 후
}
}
// 예: 씬 스코프에서
var session = sceneInstaller.Create<SessionState>();
정리
| 경로 | OnInjected 호출 조건 |
|---|---|
TryInjectTarget(..., isReinjection: false) | 필수 Scene/Global 필드 모두 성공 |
TryInjectTarget(..., isReinjection: true) | 호출 안 함 (IPoolInjectionTarget 사용) |
Create<T>() | 필드 주입 단계가 전부 성공한 경우에만 |
Awake보다 먼저/나중 같은 Unity 메시지 순서는 프로젝트의 Execution Order와 얽힙니다.
“필드가 채어진 뒤” 확실히 보장받으려면 OnInjected(또는 풀의 OnPoolGet) 에서 후처리를 두는 편이 안전합니다.