Dagger2总领

image

为了便于理解,其实可以把component想象成针管,module是注射瓶,module里面的@Provides提供依赖对象是注入的药水,build方法是插进患者(Container),inject方法的调用是推动活塞。

Java Gradle

// Add plugin https://plugins.gradle.org/plugin/net.ltgt.apt
plugins {
  id "net.ltgt.apt" version "0.5"
}

// Add Dagger dependencies
dependencies {
  compile 'com.google.dagger:dagger:2.x'
  apt 'com.google.dagger:dagger-compiler:2.x'
}

Android Gradle

// Add Dagger dependencies
dependencies {
  compile 'com.google.dagger:dagger:2.x'
  annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}

If you’re using classes in dagger.android you’ll also want to include:
额外添加

compile 'com.google.dagger:dagger-android:2.x'
compile 'com.google.dagger:dagger-android-support:2.x' // if you use the support libraries
annotationProcessor 'com.google.dagger:dagger-android-processor:2.x'

Tips

额,貌似变得更复杂了,还不如不用Dagger2呢。不过仔细想想也是可以理解的,直接组合方式虽然简单,但是具有耦合性,为了解决这种耦合,可能就会多产生一些辅助类,让这种直接的依赖关系,变为间接,降低耦合。跟大多数设计模式一样,为了达到高内聚低耦合,往往会有很多接口与类,Daager2也是如此,虽然看似复杂了些,不过这在软件工程中是值得的

依赖倒置原则
抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
抽象不应该依赖于具体,具体应该依赖于抽象。

A. 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
B. 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

依赖注入是不在类中实例化其他依赖的类,而是先把依赖的类实例化了,然后以参数的方式传入构造函数中,
让上层模块和依赖进一步解耦。

依赖注入的方式还有另外两种,一是构造器注入。二是setter

Dagger 2 极速入门 很简单的入门

Dagger2
1. 如果找不到被@Provides注释的方法提供对应参数对象的话,将会自动调用被@Inject注释的构造方法生成相应对象。
2. 区分@Provides 方法
3. 假设ActivityComponent依赖ApplicationComponent。当使用ActivityComponent注入Container时,如果找不到对应的依赖,就会到ApplicationComponent中查找。但是,ApplicationComponent必须显式把ActivityComponent找不到的依赖提供给ActivityComponent。

可能是东半球最好的dagger2文章 深度更深一些
@Qualifier不是直接注解在属性上的,而是用来自定义注解的。

神兵利器Dagger2 不错,没看完

通过registerActivityLifecycleCallbacks注入

存疑

@Component(modules = {SaladModule.class})//指明要在那些Module里寻找依赖
public interface SaladComponent {
    //注意:下面这三个方法,返回值必须是从上面指定的依赖库SaladModule.class中取得的对象
    //注意:而方法名不一致也行,但是方便阅读,建议一致,因为它主要是根据返回值类型来找依赖的
    //★注意:下面这三个方法也可以不写,但是如果要写,就按照这个格式来
    //但是当Component要被别的Component依赖时,
    //这里就必须写这个方法,不写代表不向别的Component暴露此依赖

    Pear providePear();

    Banana provideBanana();

    SaladSauce provideSaladSauce();


    //注意:下面的这个方法,表示要将以上的三个依赖注入到某个类中
    //这里我们把上面的三个依赖注入到Salad中
    //因为我们要做沙拉
    void inject(Salad salad);

}

思路整理

@Inject和@Module都可以提供依赖,那如果我们即在构造函数上通过标记@Inject提供依赖,有通过@Module提供依赖Dagger2会如何选择呢?具体规则如下:

  • 步骤1:首先查找@Module标注的类中是否存在提供依赖的方法。
  • 步骤2:若存在提供依赖的方法,查看该方法是否存在参数。
    • a:若存在参数,则按从步骤1开始依次初始化每个参数;
    • b:若不存在,则直接初始化该类实例,完成一次依赖注入。
  • 步骤3:若不存在提供依赖的方法,则查找@Inject标注的构造函数,看构造函数是否存在参数。

    • a:若存在参数,则从步骤1开始依次初始化每一个参数
    • b:若不存在,则直接初始化该类实例,完成一次依赖注入。

      1. Module并不是必需的,但Component是必不可少的;
      2. 编译后生成的Component实现类的名称是Dagger+我们所定义的Component接口的名称。
      3. Dagger2的依赖注入思想重在理解,希望小白们上手以后不单单是在使用它,更重要的是要理解它;Dagger2还有很多其他花式用法,比如在文里提到的一个Module两个方法返回值相同,还有懒加载等等,希望大家自己研究一下,以防不时之需。
在使用dagger2的过程中,在定义一些类或方法的名字的时候,要遵守一些谷歌提出的固定标准,以方便代码阅读与维护:
  1. 定义的Component和Module的名字是无所谓的,但是一般遵照以Component或Module结尾的名称;
  2. Module中用@Provides标注的方法的方法名是无所谓的,返回值是最重要的,但是一般遵照以provide开头的方法名;
  3. ==Component中返回值为void且有参的方法,方法名是无所谓的,参数是最重要的代表的是要注入的目标位置,但是方法名一般为inject;==
  4. ==Component中返回值不为void且无参的方法,方法名是无所谓的,返回值是最重要的代表的是暴露给子Component使用的依赖或者是获取的子Component的类型==。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值