dagger2_note

Author Avatar
呃哦 4月 18, 2017

@Module

提供创建类实例
使用Module来提供实例而不是直接用@Inject注解依赖类构造方法的好处是,
对于一些第三方类,不需要直接改动第三方类的代码添加@Inject

@Module //@Provide标注的方法必须在@Module里面
public class AModule{
  @Provide //表示提供某某实例
  A provideA(){return new A();}
}

@Inject

标注目标类中所依赖的其他类,同样用注解来标注所依赖的其他类的构造函数
```java
public class A{
@Inject
B b;
}

class B{
@Inject
B(){
}
}

---
## @Component
>在目标类中所依赖的其他类与其他类的构造函数之间可以起到一个桥梁的作用。  
当一个类被@Component注解时,`make project`后将会生成对应的Dagger***(这里的***为该接口名)  
当Compoent桥梁提供注入时,查找顺序首先为Module类里面提供的实例,如若找不到了再到依赖对象内去寻找@Inject注入构造器
```java
/* Module 参数 表明到时候注入时去寻找的提供实例的类模板,加大括号可以添加多个类模板 
 * dependencies 参数 表明添加另一个Component作为当前Component的依赖,则当前类自动拥有依赖项的Module提供的实例
 */
@Component(Module = {AModule.class}) 
public interface AComponent(){

}

@Singleton

单例注解,让依赖变为单例模式

  • @Inject注入下的使用
    ```java
    @Singleton
    public class A{
           @Inject
           public A(){
    
         }
 }
 ```
  • @Module注入下的使用
       @Module 
       public class AModule{
         @Singleton
         @Provide 
         A provideA(){return new A();}
       }
    
  • 以上两种对应的Component类都需要加上@Singleton
    ```java
    @Singleton
    @Component(Module = {AModule.class})
    public interface AComponent(){

}

---
## @Scope
>自定义注解来制定注入对象的作用域,从而产生局部单例的效果(例如在MainActivity单例,在LoginActivity不是),对应每个Component一个实例  
> - [以下总结来自文章 【 Dagger2 Scope 注解能保证依赖在 component 生命周期内的单例性吗?】](https://blog.piasy.com/2016/04/11/Dagger2-Scope-Instance)
> - component 的 inject 函数不要声明基类参数  
>  - Scope 注解必须用在 module 的 provide 方法上,否则并不能达到局部单例的效果
> - 如果 module 的 provide 方法使用了 scope 注解,那么 component 就必须使用同一个注解,否则编译会失败
> - 如果 module 的 provide 方法没有使用 scope 注解,那么 component 和 module 是否加注解都无关紧要,可以通过编译,但是没有局部单例效果
> - 对于直接使用 @Inject 构造函数的依赖,如果把 scope 注解放到它的类上,而不是构造函数上,就能达到局部单例的效果了
---
## @Qualifier
>限定符,当一个Module中提供了同一个类的多个实例时,可以通过限定符选择相应的实例,`@Named`是Dagger2对于`@Qualifier`一个默认实现,用法如下:
```java
@Module 
public class AModule{
        @Named("default")
        @Provide 
        A provideA(){return new A();}

        @Named("something")
        @Provide 
        A provideA2(){return new A("something");}
}

public class Main(){
  @Inject
  @Named("something")
  A somethingA;
}

也可以自定义限定符的实现

@Qualifier
@Documented
@Retention(RUNTIME)
public @interface CustonQualiftier{
        String value() default "";//如若不打算传参,不加这个参数也可以
}

而后用法同@Named相似


依赖倒置原则

抽象不应该依赖于具体,具体应该依赖于抽象

解释如下,

  • 当抽象依赖于具体时,抽象类基本很少改动(里式替换原则),当具体类A换了另一个具体类时B,便需要到抽象类修改依赖A为B
  • 当具体依赖于抽象时,由于里式替换原则,当抽象类A的实现类B替换为抽象类B时,只需要通过注入的方式修改抽象类的实现类即可,最简单的注入如 setXX() 或者 构造方法注入

MVP 模式下的依赖倒置应用:

  • Model 底层操作类,如数据库,网络请求
  • View 视图层 数据的展示,如刷新按钮,图片加载
  • Presenter 业务逻辑层, 链接V层和M层,因此持有M和V层的引用,将M层数据加以业务逻辑判断后传输给V层,

根据软件设计原则,Presenter是属于高层次模块,View是低层次模块,因此View层需要实现接口,而Presenter不需要(关于Presenter要不要实现接口是一个受争议的话题,略),View层实现IView(基类)接口后,基于里式替换原则,一个Presenter在某种情况下可以在多个View中复用。