通过接口的方式koin注入时没有使用binds指明接口类型导致崩溃

135 阅读1分钟

1 崩溃堆栈

显示没有定义ITagSearchTrackHelper接口的实现

org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'com.xxx.track.ITagSearchTrackHelper'. Check your definitions!

2 问题复现

  1. 在父节点中向子节点抛出了searchResultTrackHelper实例 在这里插入图片描述 其中searchResultTrackHelper为SearchNoteTrackHelper类型 在这里插入图片描述
  2. SearchNoteTrackHelper是一个接口,继承了IBaseResultTrackHelper、ITagSearchTrackHelper和IFilterPanelTrackHelper接口 在这里插入图片描述
  3. 在TagSearchItemRootSectionGroup中注入了ITagSearchTrackHelper类型的trackHelper 在这里插入图片描述
  4. 当点击tag search的item项时就发生了崩溃

3 问题分析

3.1 Kolin注入的核心机制

  • Koin 的“定义注册表”是用三元组做键:类型 KClass + 可选 qualifier + scope。
  • 你写 scoped { searchResultTrackHelper } 时,Koin只会以“实现类的具体类型”注册该实例,比如 SearchNoteTrackHelper。
  • 依赖解析时,injectFrom<ITagSearchTrackHelper>() 会用“接口类型”当 key 去查。因为注册表里只有“具体类”的键,没有“接口”的键,故报NoBeanDefFoundException的错误。

3.2 binds 的作用

  • binds arrayOf(ITagSearchTrackHelper::class) 会在同一条定义上为该实例额外注册“别名类型”。等价于把这一个实例同时挂到多个类型键上:
    • SearchResultNoteController(实现类)
    • ITagSearchTrackHelper(接口)
  • 因此,不管你用实现类还是接口去 inject,都能匹配到同一个实例。

4 解决方法

新增ITagSearchTrackHelper接口类型映射 在这里插入图片描述

报错的根因是“按接口查找,但注册时没有把实例声明为接口类型”。加上 binds 就是给实例增加“接口类型别名”,让 Koin 的类型匹配成立,解析自然通过。