Search code examples
androidkotlinkoin

Dependency injection with Koin


I have a class that uses Dagger 2 for dependency injection. Now I want to switch to Koin for dependency injection. There are modules in Koin and I want to make a module out of the class or whatever can be done.

@Module
class NetModule(private val baseUrl: String) {

@Provides
@Singleton
fun providesOkHttpClient(
        httpLoggingInterceptor: HttpLoggingInterceptor): OkHttpClient = OkHttpClient.Builder().addInterceptor(
        httpLoggingInterceptor).build()

@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
    val interceptor = HttpLoggingInterceptor(
            HttpLoggingInterceptor.Logger { message -> Logger.d("NETWORK: $message") })
    interceptor.level = HttpLoggingInterceptor.Level.NONE
    return interceptor
}

@Provides
@Singleton
fun providesMoshi(): Moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()

@Provides
@Singleton
fun providesRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): Retrofit {
    return Builder().client(okHttpClient).baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
}

@Provides
@Singleton
fun providesApiInterface(retrofit: Retrofit): ApiInterface = retrofit.create(
        ApiInterface::class.java)
}

Solution

  • Koin uses a DSL for describing modules. Usually you'd declare the module itself on a top-level. Since you need to provide baseUrl, you'd have to create a factory for it.

    The @Provides annotation is completely irrelevant, but @Singleton needs to be translated and does so with single. To retrieve the dependencies, just call get().

    fun netModule(baseUrl: String) = module {
    
        single {
            HttpLoggingInterceptor(
                HttpLoggingInterceptor.Logger { message ->
                    Logger.d("NETWORK: $message")
            }).apply {
                level = HttpLoggingInterceptor.Level.NONE
            }
        }
    
        single {
            OkHttpClient.Builder()
                .addInterceptor(get<HttpLoggingInterceptor>())
                .build()
        }
    
    
        single {
            Moshi.Builder()
                .add(KotlinJsonAdapterFactory())
                .build()
        }
    
        single {
            Retrofit.Builder()
                .client(get())
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
        }
    
        single { get<Retrofit>().create(ApiInterface::class.java) }    
    }