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

Use*_*ase 6 android dependency-injection kotlin 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)
        }
    } 
}

Run Code Online (Sandbox Code Playgroud)

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

get()我可以在调用时传递一些参数以便获得不同的实例吗?任何建议都会受到赞赏。

小智 18

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

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

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

.client(get(named("auth")))
Run Code Online (Sandbox Code Playgroud)


Shw*_*han 5

你可以像下面这样(使用 koin 最新版本的命名属性)。另外,为什么我使用 single 和 factory 因为

single—声明给定类型的单例定义。Koin 仅保留此定义的一个实例

factory?—?声明给定类型的工厂定义。Koin 每次都会给出一个新实例

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在您的活动或视图模型中

protected val apiServiceWithoutHeader: ApiService by inject(named(WITH_OUT_HEADER))
protected val apiServiceWithHeader: ApiService by inject(named(WITH_HEADER))
Run Code Online (Sandbox Code Playgroud)

使用上述对象调用适当的 API