① 앞의 글에서 작성한 생성자 주입은 특정 객체를 생성할 때 생성자의 매개변수를 통해 객체를 주입하는 것이고, 이번 글에서 작성할 필드 주입은 이미 생성되어있는 객체의 필드에 객체를 주입하기 위해 사용할 수 있는 방법입니다.
② Andorid 에서는 Activity 와 같은 컴포넌트 객체는 개발자가 직접 생성하는 것이 아니라 Android 시스템에서 객체를 생성하여 생명주기를 관리합니다. 그렇기 때문에 Activity 와 같은 Android 컴포넌트에 특정 객체를 주입하기 위해서는 생성자 주입이 아닌 필드 주입을 사용하여야 합니다.(생성자 주입을 하기 위해서는 Dagger 에서 해당 객체를 직접 생성해야 하는데 그것이 불가능하기 때문에)
③ 이 글에서는 Dagger 가 생성한 코드를 기반으로 필드 주입 시 작업 흐름에 대해 작성하였습니다.
④ 예제 코드는 아래와 같습니다.
Component interface
@Component(modules = [CarModule::class])
interface CarComponent {
fun inject(activity: MainActivity)
}
Component 와 연결된 Module class
@Module
class CarModule {
@Provides
fun provideCar(): Car {
return Car()
}
}
필드에 주입될 class
class Car {
fun drive() {
Log.d("Dagger2", "drive() call")
}
}
Dagger 에 의해 필드 주입을 받을 class
class MainActivity : AppCompatActivity() {
@Inject
lateinit var car: Car
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val component = DaggerCarComponent.create()
component.inject(this)
car.drive()
}
}
⑤ 필드 주입 시 작업 흐름
⑴ MainActivity 클래스에서 Component 의 Member-Injection Method 를 호출하여 필드 주입을 트리거합니다.
@Override
public void inject(MainActivity activity) {
injectMainActivity(activity);
}
private MainActivity injectMainActivity(MainActivity instance) {
MainActivity_MembersInjector.injectCar(instance, CarModule_ProvideCarFactory.provideCar(carModule));
return instance;
}
⑵ Dagger 에서 생성한 ProvideFactory 클래스에서 Component 와 연결된 Module 을 통해 주입해야 할 클래스의 인스턴스를 가져옵니다.
public static Car provideCar(CarModule instance) {
return Preconditions.checkNotNullFromProvides(instance.provideCar());
}
@Provides
fun provideCar(): Car {
return Car()
}
⑶ Dagger 에서 생성한 MemberInjector 클래스의 "Component 메서드명 + 주입할 인스턴스 타입" 형태의 static 메서드를 호출합니다. 이 메서드에서 실제로 필드 주입이 발생합니다. 이때 첫번째 매개변수는 주입받을 인스턴스이고 두번째 매개변수는 주입할 인스턴스입니다.
@InjectedFieldSignature("com.dagger2test.MainActivity.car")
public static void injectCar(MainActivity instance, Car car) {
instance.car = car;
}
⑤ 요약
외부 클래스(예: MainActivity)에서 Component 에 정의된 Member-Injection Method 를 호출하여 필드 주입을 트리거하면 가장 먼저 주입해야 할 인스턴스(예: Car)를 생성합니다. 그 다음 Dagger 에서 생성한 MemberInjector 클래스의 "Component 메서드명 + 주입할 인스턴스 타입"의 static 메서드(예: injectCar)에 주입받을 인스턴스와 주입할 인스턴스를 매개변수로 전달하며 호출합니다. 마지막으로 static 메서드에서 첫번째 매개변수를 통해 받은 인스턴스에 @Inject 어노테이션이 선언되어있는 필드에 두번째 매개변수 참조를 저장하며 필드 주입을 완성합니다.
'dagger' 카테고리의 다른 글
| Dagger2 with ViewModel (1) | 2022.12.29 |
|---|---|
| Dagger2 Singleton (0) | 2022.12.03 |
| Dagger2 생성자 주입 (0) | 2022.11.23 |
| Dagger2 시작 (0) | 2022.11.22 |