[Dagger] Assisted Injection
#
Assisted injection 은 object 를 만들 때 몇몇 param 은 DI framework (Dagger 등) 로부터 주입받고, 나머지는 user 에 의해 creation time 에 제공받는 것을 이야기한다.
Factory 가 이 param 들을 조합해서 object 를 생성한다.
Dagger assisted injection
#
Dagger 의 assisted injection 을 사용하려면, constructor 에 @AssistedInject 를 마킹하고, assisted param 들에 대해 @Assisted 를 마킹해줘야 한다.
class MyDataService @AssistedInject constructor(
dataFetcher: DataFetcher,
@Assisted config: Config
) {
// ...
}
#
그 다음 할 일은 @AssistedFactory 로 마킹된 factory 의 정의이다.
이 factory 에는 @Assisted 로 마킹된 param 들을 '순서대로' 받으며, @AssistedInject 로 마킹된 녀석을 return 하는 abstract method 정의를 해주어야 한다.
@AssistedFactory
interface MyDataServiceFactory {
fun create(config: Config): MyDataService
}
#
위와 같은 작업을 해주면 Dagger 는 assisted factory 구현을 만들고, binding 을 제공해준다.
이 factory 는 DI 대상이 된다.
class MyApp {
@Inject lateinit var serviceFactory: MyDataServiceFactory;
fun setupService(config: Config): MyDataService {
val service = serviceFactory.create(config)
...
return service
}
}
Comparison to @Inject
#
@AssistedInject constructor 와 @Inject constructor 는 아래의 차이가 있다.
- @AssistedInject 는 바로 inject 될 수 없다. @AssistedFactory type 만 바로 inject 가능하다. Constructor 에 assisted param 이 없더라도 유효하다.
- @AssistedInject type 은 scope 될 수 없다.
Disambiguating @Assisted parameters with the same type
#
@Assisted param 이 같은 type 을 가지고 있다면, 그들을 identifier 를 주어 구분해야만 한다.
이는 @Assisted("name") 을 이용해서 한다.
class MyDataService @AssistedInject constructor(
dataFetcher: DataFetcher,
@Assisted("server") serverConfig: Config,
@Assisted("client") clientConfig: Config
) { }
@AssistedFactory
interface MyDataServiceFactory {
fun create(
@Assisted("server") serverConfig: Config,
@Assisted("client") clientConfig: Config
): MyDataService
}
What about AutoFactory and Squre's AssisstedInject?
#
Dagger 유저라면 Dagger 의 것을 쓰는 것이 추천된다.
AutoFactory, Square's AssistedInject 은 Dagger 의 것보다 먼저 나왔으며, Dagger 와 통합하기 위해서는 boilerplate 가 요구되기 때문.
끝
참고 : https://dagger.dev/dev-guide/assisted-injection.html