Android开发从Dagger2迁移至Kodein的感受

2020-11-22 23:18:59

参考地址 Android开发从Dagger2迁移至Kodein的感受

我是却把清梅嗅,一个普通的Android开发者。去年,我写了一系列关于Android开发者依赖注入框架 Dagger2dagger.android 的博客:

Android 神兵利器Dagger2使用详解(一)基础使用
Android 神兵利器Dagger2使用详解(二)Module&Component源码分析
Android 神兵利器Dagger2使用详解(三)MVP下的使用
Android 神兵利器Dagger2使用详解(四)Scope注解使用及源码分析
告别Dagger2模板代码:dagger.android使用详解
告别Dagger2模板代码:dagger.android原理分析

最近个人在尝试构建 Kotlin版本 的Android MVVM开发框架,在依赖注入框架的选型上,我最终选择了 Kodein

这是一个非常轻量级的DI框架,相比于配置繁琐的Dagger(繁琐的配置也是导致Dagger学习成本一直居高不下的原因!),它的配置过程更清晰且简单,并且,这个库的源码也是 Kotlin 的。

有同学说,虽然 Dagger2 配置很繁琐,但 dagger.android 已经大大减少了模板代码的配置。确实如此,但它终究是通过编译器自动生成 Java 代码的库,我已经厌倦使用它了......请不要再劝我将它掺入 Kotlin 的项目中了。

扯了这么多,请阅读正文吧, 作者简单阐述了 Kodein 的使用感受,通过和 Dagger2 对比,阐述库本身的优缺点,希望能给同行一些参考。

不久之后,我会专门写一篇文章剖析Kodein入门教程项目中的应用 ,敬请期待。

2018.9追加

Kodein的中文博客详解已更新:

告别Dagger2,Android的Kotlin项目中使用Kodein进行依赖注入

正文


从Dagger2迁移至Kodein的感受

有些时候,Dagger2可能会有点过于复杂。 例如,当每个 Activity 都有一个 Scope(作用域) 时,每个屏幕都必须实现一个Scope,一个Module和一个Component。

对于Kotlin的开发者来讲,Kodein将是你的救星。

1.Kodein并不是一个依赖注入(DI)框架

虽然 Kodein 全名为 KOtlin DEpendency INjection,但Kodein并不是一个真正的依赖注入框架。 他们的官方文档将其称作 依赖检索容器

Kodein使用容器来传递依赖关系,这与Dagger2有什么不同? 让我们看一下从文档的Kodein示例代码:

val kodein = Kodein {
    bind<Dice>() with provider { RandomDice(0, 5) }
    bind<DataSource>() with singleton { SqliteDS.open("path/to/file") }}class Controller(private val kodein: Kodein) {
    private val ds: DataSource = kodein.instance()}

第一个表达式创建了一个容器,然后将容器传递给Controller。这之后,将检索依赖项的工作 委托 给了Controller。

而使用Dagger2,该示例将如下所示:

Dagger2中没有 容器 的概念。 依赖关系通过构造函数,属性或方法注入。 Controller不知道dataSource的来源——这是Dagger2和Kodein之间的根本区别。

2.Kodein中可以使用“非常简单易读的声明性DSL”

官方文档是这样描述的, 上面的代码示例也正是这样做的。 它的好处是使代码更加紧凑,嗯,仅此而已 :)

3.使用了Kodein的开源项目?

网上有大量资料可供学习Dagger2:教程,博客文章,开源项目; 它们非常有用。

对于Kodein? 并不多😔我仍然有很多关于如何正确使用Kodein的疑问。

4 Kodein有很多方式可以实现依赖注入

以上文的代码为例,如下所示:

val kodein = Kodein { ... }class Controller(val dataSource: DataSource)val controller = kodein.newInstance { Controller(instance()) }

现在Controller不依赖于一个容器,这更类似Dagger2通过构造函数传递依赖关系的的实现方式。

或者我们可以这样做:

val kodein = Kodein { ... }class Controller {
    private val injector = KodeinInjector()
    private val dataSource: DataSource by injector.instance()
    
    init {
        injector.inject(kodein)
        // use dataSource
    }}

这类似于Dagger2注入属性的实现方式。

而且,如果你“勇敢”地在你的应用程序中滥用反射,你甚至可以将JSR330与Kodein一起使用。

关键是,Kodein提供了许多注入依赖关系的方法, 您不必总是将容器传递给对象。

5.你的类可能依赖于Kodein

在使用Dagger2的项目中,您的类将取决于JSR330标准的注解(译者注,@Inject等注解)。 这些类并不依赖Dagger2。

在使用Kodein的项目中,您的类可能需要依赖于Kodein; 这一切都取决于使用哪种实现方式。 在第一个示例中,Controller依赖于Kodein容器。 在注入器示例中,Controller依赖于KodeinInjector。

6.Kodein在运行时判断依赖关系

如果您忘记将实例绑定到容器,则只会在运行时收到错误消息。 而使用Dagger2,您在编译时会收到错误。

7.Kodein容器太通用了

在Dagger2中,我们在定义好的方法中声明模块和组件。 它们可以让Contract了解到谁被谁依赖,依赖被注入在哪里。

但是,Kodein容器没有提供或保存的任何类型信息。 这意味着,对于类型系统,这两个容器是相同的:

val kodein = Kodein {
        bind<Dice> with provider { RandomDice(0, 5) }}val foo = Kodein {
        bind<UserRepository> with singleton { UserRepo() }}

如果你很幸运,不小心将foo而不是kodein传递给一个对象。 该项目将成功编译,但它将在运行时发生崩溃。

还有?

我喜欢在这个小项目中使用Kodein。 我认为它的DSL非常简单,功能强大且简洁。 但我确实遇到了只在运行时捕获的问题。

我可能会在小项目上再次使用Kodein。 对于更大的项目,我可能还是需要保持观望的态度。



作者:却把清梅嗅
链接:https://www.jianshu.com/p/e5eef49570b9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


  • 2019-10-14 21:18:57

    Comparable 的 使用

    要做这个呢,我们也是用到了Arrays.sort 这个排序的方法!但不同的是,我们之前用的是int数组,现在我们用的是这个UserBean数组。如果你想对这个UserBean数组进行排序,你要多做一件事,就是让这个 UserBean类去 实现Comparable 的接口,并重写 里面  comparaTo 的方法。注意,这个接口是可以提供泛型的 ———————————————— 版权声明:本文为CSDN博主「sdn_bt496」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明

  • 2019-10-15 05:53:20

    xUtils 里的DbUtils使用心得

    使用xUtils做Android数据库开发非常简便和得心应手,而且它本身还支持很多查询功能,比如一对多,select count和自定义sql查询等,并且支持事务(默认关闭) 下面是官方sample给的代码和我的一些使用心得 首先是两个实体类,对应两张表,这两张表中有一对多的关系

  • 2019-10-15 09:18:48

    腾讯 Android 面试笔试总结

    Activity中的几种启动模式 Android消息机制 IntentService 事件分发 Android性能优化、内存优化 内存优化 View的绘制 Eventbus原理 Rxjava的操作符有哪些,说说他们的作用 线程锁 锁方法和类对象啥的有啥区别 AsyncTask原理 说说MVP和MVVM的特点 Android中用到的观察者模式有哪些地方 说说google新出的Lifecycle框架 okhttp原理 Retrofit原理 RecyclerView源码、缓存分析 Binder机制 Android Jetpack Kotlin Activity中的几种启动模式

  • 2019-10-15 09:20:49

    SpringBoot注解梳理

    @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration注解。其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文。 @Configuration 等同于spring的XML配置文件;使用Java代码可以检查类型安全。 @EnableAutoConfiguration 自动配置。 @ComponentScan 组件扫描,可自动发现和装配一些Bean。 @Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。 @RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。 @Autowired自动导入。 @PathVariable获取参数。 @JsonBackReference解决嵌套外链问题。 @RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

  • 2019-10-15 09:52:00

    动图解释递归,按值传递和按引用传递的区别,线性查找和二分查找,二叉查找树

    对于大部分人,数据结构一直是一个短板,当然我也是,不是学不会,而是容易忘,就拿最简单的排序来说吧,当时学习的时候明明已经弄得很清楚了,过了一段时间不用又忘记了,还要重新再看一遍,不知道有多少小伙伴和我有一样的烦恼。今天让我们用用动图的方式学习一下数据结构中的递归和二分查找吧,这种讲解方式非常生动,而且非常容易记住和理解。