### **생성자 주입 (Constructor Injection)**
일반적으로 의존성들은 처음 해결(resolved)될 때 (예외적인 경우를 제외하고) 구성(constructed)되고 주입됩니다.
- **의존성 주입 방식:** 의존성을 필요로 하는 클래스를 등록할 때, 해당 의존성을 인자로 받는 생성자를 제공하면 VContainer가 나머지를 처리합니다.
**예시:**
`ClassA.cs`
코드 스니펫
```
class ClassA
{
readonly IServiceA serviceA;
readonly IServiceB serviceB;
readonly SomeUnityComponent component;
public ClassA(
IServiceA serviceA,
IServiceB serviceB,
SomeUnityComponent component)
{
this.serviceA = serviceA;
this.serviceB = serviceB;
this.component = component;
}
}
```
- 위 코드 예시는 VContainer API를 사용하지 않습니다. 이는 `ClassA`가 VContainer에 전혀 종속되지 않음을 의미합니다. 필요하다면 VContainer를 사용하지 않고도 동일한 생성자로 `ClassA` 인스턴스를 수동으로 생성할 수 있습니다.
**주의 (CAUTION):**
- Unity는 빌드에서 사용되지 않는 코드를 제거(stripping)하지만, 리플렉션이나 IL 코드 생성(VContainer의 경우처럼)이 관련될 때는 종종 실수를 합니다.
- **생성자가 제거되지 않도록 하려면 `link.xml` 파일을 사용하거나, 하나의 생성자에 `[Inject]` 속성을 추가해야 합니다.** 이는 메서드에도 동일하게 적용됩니다.
**`[Inject]` 속성 사용 예시:**
C#
```
[Inject]
public ClassA(
IServiceA serviceA,
IServiceB serviceB,
SomeUnityComponent component)
{
// ...
}
```
**참고 (NOTE):**
- **현재 생성자에서는 선택적 의존성(optional dependencies)이 지원되지 않습니다.** 만약 생성자 의존성이 누락된 경우, VContainer는 컨테이너 빌드 또는 유효성 검사 시 예외를 발생시킵니다.
- 클래스에 두 개 이상의 생성자가 있는 경우, VContainer는 **가장 많은 인자(arguments)를 가진 생성자를 선택**합니다. 동일한 수의 인자를 가진 생성자가 여러 개 있는 경우, `[Inject]` 속성이 있는 생성자가 선호됩니다.
**생성자 주입을 권장하는 이유:**
VContainer는 가능한 한 생성자 주입을 사용하도록 권장합니다. 그 이유는 다음과 같습니다:
- **가장 간단한 주입 형태:** 사용하기 가장 직관적이고 간단합니다.
- **안전한 의존성 해결 보장:** VContainer와 함께 사용될 경우, 클래스는 자신의 의존성이 해결되었음을 안전하게 가정할 수 있습니다 (그렇지 않다면 생성되지 않았을 것이기 때문입니다).
- **클래스 내부에 마법(magic)이 없음:** 클래스 자체에는 VContainer 관련 코드가 없으므로, VContainer를 사용하지 않고도 (예: 테스트용으로) 인스턴스를 생성할 수 있습니다.
- **명확한 클래스 의존성:** 클래스의 의존성이 생성자를 통해 명확하게 드러납니다. 이는 클래스가 너무 많은 책임을 가지고 있는지 (생성자 인자가 너무 많아질 때) 판단하기 쉽게 해줍니다.
**MonoBehaviour:**
- **MonoBehaviour는 생성자를 지원하지 않습니다.** 따라서 MonoBehaviour에 의존성을 주입해야 할 경우에는 대신 **메서드 주입(Method Injection)** 또는 **속성/필드 주입(Property/Field Injection)**을 사용해야 합니다.
**경고 억제 (Suppressing Warnings):**
- Unity는 JetBrains에서 정의한 코드 분석 속성 세트를 포함하고 있으며, 일부 IDE(Rider 포함)는 이를 코드 분석에 사용합니다.
- 만약 IDE가 주입 생성자를 "사용되지 않음(unused)"으로 표시한다면, `[UsedImplicitly]` (선택적으로 `ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature`와 함께) 속성을 적용할 수 있습니다.
**예시:**
C#
```
public class Dependency
{
[UsedImplicitly (ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
public Dependency (GameContext game, StatusContext status)
{
_game = game;
}
}
// 이 클래스와 생성자는 사용되지 않는 것으로 표시되지 않지만, status 매개변수는 표시됩니다.
```
- 생성자나 메서드에 위와 같이 주석을 달면, Rider는 생성자(및 클래스)가 사용되지 않는 것으로 표시되는 것을 방지합니다. 그러나 해당 생성자 내의 **사용되지 않는 매개변수는 여전히 그렇게 표시될 수 있습니다.**
- 다른 IDE의 결과는 다를 수 있습니다.
### 요약
VContainer에서 생성자 주입의 기본 원리와 사용법, 그리고 이 방법이 왜 선호되는지에 대한 이유를 상세히 설명합니다. 또한 Unity의 코드 스트리핑 문제 해결책과 MonoBehaviour에 생성자 주입이 불가능하다는 점을 명확히 안내합니다.
---
이전 : [[2.2 Hello World]] | 다음 : [[3.2 Method Injection]]