일반적으로 A에 대한 Interface를 만들면, 하나의 구상객체만 주입하여 사용하는것이 일반적입니다.
하지만 다형성 측면에서, 필요에 따라 원하는 구상 객체를 주입받아야 할때가 있습니다.
보통 다양한 API를 사용할때 이런 상황이 생기는데요. 아래의 상황을 봅시다.
@Provides
@Singleton
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://여기어떄")
.addConverterFactory(
json.asConverterFactory("application/json".toMediaType()),
)
.addCallAdapterFactory(ResultCallAdapterFactory())
.build()
}
@Singleton
@Provides
fun provideKmdbAPI(
// 이 Retrofit은 반드시 위의것을 주입받는다.
retrofit: Retrofit,
): KmdbAPI = retrofit.create(KmdbAPI::class.java)
지금까지 해당 API를 만들고 잘 이용해왔었습니다.
추가요건으로 다른 baseUrl이 필요한 Retrofit을 만들어야한다면 어떻게 바뀌어야할까요?
이를 위해 @Named
어노테이션을 이용하면 해결할 수 있습니다.
@Named("여기어때")
fun provideRetrofit1(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://여기어떄")
.addConverterFactory(
json.asConverterFactory("application/json".toMediaType()),
)
.addCallAdapterFactory(ResultCallAdapterFactory())
.build()
}
@Named("야놀자")
fun provideRetrofit2(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://야놀자")
.addConverterFactory(
json.asConverterFactory("application/json".toMediaType()),
)
.addCallAdapterFactory(ResultCallAdapterFactory())
.build()
}
@Singleton
@Provides
fun provide여기어때API(
// 이 Retrofit은 반드시 위의것을 주입받는다.
@Named("여기어때") retrofit: Retrofit,
): KmdbAPI = retrofit.create(여기어때API::class.java)
@Singleton
@Provides
fun provide야놀자API(
// 이 Retrofit은 반드시 위의것을 주입받는다.
@Named("야놀자") retrofit: Retrofit,
): KmdbAPI = retrofit.create(야놀자API::class.java)
@Named
를 통해 필요한 추상객체를 주입받을 수 있습니다.
그렇다면 Koin에서는 어떻게 해야할까요?
koin은 single 블록의 인자로 named
를 받습니다.
single(named ="여기어때"){여기어때API()}
single(named ="야놀자"){야놀자API()}
해당 객체를 주입받을때는 어떻게 해야할까요?
inject()
함수의 인자중에 모듈에 적었던 동일한 이름을 넘겨주시면 됩니다.
val 여기어때 : Retrofit by inject(named("여기어때")
val 야놀자 : Retrofit by inject(named("야놀자")
이상입니다!
Dagger Hilt 사용하여 의존성 주입(DI) 하기
[Koin] named 메서드를 이용해 같은 Type 객체 구분하기