【问题标题】:Koin Scope and InterfaceKoin 范围和接口
【发布时间】:2018-09-07 11:34:29
【问题描述】:

我在我的项目中使用Koin di 库。 lib 的版本是 1.0.0-RC-1

我的模块

val appModule = module {
    scope("UserScope") { UserToaster(androidContext()) as Toaster }
    scope("AnonScope") { AnonToaster(androidContext()) as Toaster }
}

我在我的 Application 类中开始 koin 并创建了 scope

override fun onCreate() {
    super.onCreate()

    startKoin(this, listOf(appModule))
    getKoin().getOrCreateScope("AnonScope")
}

接下来我尝试将 Toaster 的实现从当前范围注入到 Activity 中的变量中。代码如下:

private val toaster: Toaster by inject(scope = "AnonScope")

在这之后我得到一个错误:

Caused by: org.koin.error.DependencyResolutionException: Multiple definitions found for type 'interface com.example.nkirilov.playground.Toaster (Kotlin reflection is not available)' - Koin can't choose between :
    Scope [name='UserScope',class='com.example.nkirilov.playground.Toaster']
    Scope [name='AnonScope',class='com.example.nkirilov.playground.Toaster']
    Check your modules definition, use inner modules visibility or definition names.

我不明白为什么这不起作用(如果使用具有不同名称的 single - 它会起作用)。那是koin错误吗?如何避免这个错误?

【问题讨论】:

    标签: android koin


    【解决方案1】:

    我是这样实现的

    模块

    val navigationModule = module {
        scope(DI.APP_SCOPE) { ClassA().create }
        scope(DI.APP_SCOPE) { get(scopeId = DI.APP_SCOPE).classB }
        scope(DI.APP_SCOPE) { get(scopeId = DI.APP_SCOPE).classC }
    }
    
    val authModule = module {
        scope(DI.AUTH_SCOPE) { ClassA.create(ChildClassB(get(scopeId = DI.APP_SCOPE))) }
        scope(DI.AUTH_SCOPE) { get(scopeId = DI.AUTH_SCOPE).classB }
        scope(DI.AUTH_SCOPE) { get(scopeId = DI.AUTH_SCOPE).classC }
    }
    

    主要活动

    private val classC: ClassC by inject(scope = getKoin().getOrCreateScope(APP_SCOPE))
    

    AuthActivity

    private val classC: ClassC by inject(scope = getKoin().getOrCreateScope(DI.AUTH_SCOPE))
    

    【讨论】:

      【解决方案2】:

      您的定义在 Koin 中具有相同的名称。当前版本 (~1.0.*) 通过自动解析类型及其会话 id,避免您指定要使用的范围。

      你能避免用相同的类型来描述你的定义吗,比如:

      val appModule = module {
          scope("UserScope") { UserToaster(androidContext()) }
          scope("AnonScope") { AnonToaster(androidContext()) }
      }
      

      否则我们需要一个特性来指定解析类型时使用的范围。您可以通过以下方式解决它:

      val userScope = getScope("UserScope")
      get<Toaster>(scope = userScope)
      

      【讨论】:

      • 它对我不起作用。我在 Github 上创建了一个示例项目,如果你有空,请检查一下。 [此处链接:] (github.com/KolinLoures/TestScopeKoin)。 TIA
      • 让我检查一下?
      • 编辑了我的评论。你现在可以直接使用你的类型吗?
      • 不幸的是,我不能。在我的工作项目中,我需要根据创建的范围来设置实现。可能,是否有另一种方法来实现这个想法?
      • 这样有点难找,但主要是可见性不受范围的限制。您可以在 github 上提出问题。
      猜你喜欢
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-29
      • 2020-01-24
      • 1970-01-01
      相关资源
      最近更新 更多