You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Koin中配置基类与实现类的同一实例依赖注入?

在Koin中注入同一子类实例到基类引用的实现方法

这个需求在Koin里实现起来很直接,核心就是让基类的依赖定义指向子类的同一个实例,下面给你两种常用的写法:

方法一:显式关联实例

这种方式先注册子类的实例,再让基类的依赖指向这个已注册的实例,逻辑非常直观:

// 定义你的Koin模块
val appModule = module {
    // 先注册SpecificClass的实例,这里用single表示单例(全局唯一)
    single<SpecificClass> { SpecificClass() }
    // 让BaseClass的依赖获取同一个SpecificClass实例
    single<BaseClass> { get<SpecificClass>() }
}

这样当你在类中分别注入SpecificClassBaseClass时,拿到的会是同一个对象:

class SomeClassA {
    // 注入SpecificClass实例
    private val specificClass: SpecificClass by inject()
}

class SomeClassB {
    // 注入的是同一个SpecificClass实例,用BaseClass类型引用
    private val baseClass: BaseClass by inject()
}

方法二:使用bind关键字简化写法

Koin提供了bind关键字,可以让我们在注册子类实例的同时,直接绑定它的基类类型,写法更简洁:

val appModule = module {
    // 注册SpecificClass实例,并绑定BaseClass类型
    single<SpecificClass> { SpecificClass() } bind BaseClass::class
}

// 或者也可以这样写(效果完全一致)
val appModule = module {
    single { SpecificClass() } bind BaseClass::class
}

这种方式和方法一的效果完全相同:当请求BaseClass类型的依赖时,Koin会返回你注册的SpecificClass实例,两者是同一个对象。

关于作用域的注意事项

上面的例子用的是single(单例作用域),如果你需要其他作用域,只需要替换对应的关键字即可,bind关键字同样适用:

  • factory:每次注入都创建新的实例(注意:此时每次请求SpecificClassBaseClass都会生成新对象,同一个类中同时注入两者会得到不同实例)
  • scoped:在指定作用域内唯一(比如Activity、ViewModel作用域)

示例代码:

// factory作用域示例
val appModule = module {
    factory<SpecificClass> { SpecificClass() } bind BaseClass::class
}

// scoped作用域示例
val appModule = module {
    scoped<SpecificClass> { SpecificClass() } bind BaseClass::class
}

内容的提问来源于stack exchange,提问作者Archie G. Quiñones

火山引擎 最新活动