是否可以创建同一对象的不同实例并通过将参数传递给 Koin 中的 get() 函数来访问它们?

Is it possible to create different instances of the same object and access them by passing parameters to get() function in Koin?

我正在使用 Koin 作为我的应用程序的 DI。我创建了一个模块:

object NetworkModule {
    fun get() = module {
        single {
            val authenticationInterceptor = Interceptor { chain ->
                // Request customization goes here
            }

            OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(authenticationInterceptor) //Not all clients might have this interceptor
                .build()
        }

        single {
            Retrofit.Builder()
                .baseUrl("example.com")
                .client(get(/* I would like to send some paramter here */))
                .addConverterFactory(GsonConverterFactory.create(get()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(Api::class.java)
        }
    } 
}

如何创建具有不同参数集或不同实例化的不同 HttpClientRetrofit 实例?例如,在某些情况下,我可能需要 OkHttpClientAutheniticationInterceptor,而在其他一些情况下,我的客户可能不需要使用它。

我可以在调用get()时传递一些参数,以便我可以得到不同的实例吗?任何建议将不胜感激。

您可以使用命名属性 - 例如

single<OkHttpClient>(named("auth")){
// here you pass the version with authinterceptor
}
single<OkHttpClient>(named("noAuth")){
// here you pass the version without authinterceptor
}

然后在您的 get() 方法中传递名称,例如

.client(get(named("auth")))

You can do like below (Use koin latest version for named property).Also why I use single and factory because

single— declare a singleton definition of given type. Koin keeps only one instance of this definition

factory — declare a factory definition of given type. Koin gives a new instance each time

const val WITH_AUTH: String = "WITH_AUTH"
const val WITH_OUT_AUTH: String = "WITH_OUT_AUTH"

val remoteModule = module {
factory(named("HEADERS")) {
        val map = it.get<MutableMap<String, String>>(0)
        Interceptor { chain ->
            val original = chain.request()
            val request = original.newBuilder()
            map.forEach { entry ->
                request.addHeader(entry.key, entry.value)
            }
            chain.proceed(request.build())
        }
    }

factory(named("auth")) {
        OkHttpClient.Builder().apply {
            map["AUTHORIZATION"] = "token"

            readTimeout(1, TimeUnit.MINUTES)
            connectTimeout(2, TimeUnit.MINUTES)
            writeTimeout(1, TimeUnit.MINUTES)
            addInterceptor(get(named("HEADERS"), parameters = {
               parametersOf(map)
            }))
        }.build()
    }

factory(named("auth")) {
        Retrofit.Builder()
                .baseUrl("base_url")
                .client(get(named("auth")))
                //.addCallAdapterFactory()
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService::class.java)
    }

single(named("noAuth")) {
        val map = mutableMapOf(ACCEPT to CONTENT_TYPE)
        OkHttpClient.Builder().apply {
            readTimeout(1, TimeUnit.MINUTES)
            connectTimeout(2, TimeUnit.MINUTES)
            writeTimeout(1, TimeUnit.MINUTES)
            addInterceptor(get(named("HEADERS"), parameters = {
                parametersOf(map)
            }))
          
        }.build()
    }

single(named("noAuth")) {
        Retrofit.Builder()
                .baseUrl("base_url")
                .client(get(named("noAuth")))
                //.addCallAdapterFactory()
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(ApiService::class.java)
    }
}

Now in your activity or viewModel

protected val apiServiceWithoutHeader: ApiService by inject(named(WITH_OUT_HEADER))
protected val apiServiceWithHeader: ApiService by inject(named(WITH_HEADER))

以上对象调用合适API