美文网首页Android开发Android技术知识
Dagger 2学习与探索(四)

Dagger 2学习与探索(四)

作者: akak18183 | 来源:发表于2017-08-23 09:44 被阅读0次

    上一期介绍了Dagger是如何应对多个同类型变量的,这一期主要介绍,在对原对象不做任何修改的情况下如何将其注入。

    主体代码

    现在将ClassA的所有标注全都去掉:

    public class ClassA {
    
      private int a;
      private int b;
    
      public ClassA(int a, int b) {
        this.a = a;
        this.b = b;
      }
    
      public int getA() {
        return a;
      }
    
      public int getB() {
        return b;
      }
    }
    

    好了,那么现在Dagger要从哪里知道ClassA的构造函数以及参数呢?
    答案是在Module里。现在Dagger自己无法查到ClassA的带@Inject标注的构造器了,于是转而要Module @Provides一个出来,具体如下:

    @Module
    public class ModuleA {
      private int a;
      private int b;
    
      public ModuleA(int a, int b) {
        this.a = a;
        this.b = b;
      }
    
      @Provides
      @Named("a")
      int provideIntA() {
        return a;
      }
    
      @Provides
      @Named("b")
      int provideIntB() {
        return b;
      }
    
      @Provides
      ClassA provideClassA(@Named("a") int a, @Named("b") int b) {
        return new ClassA(a, b);
      }
    }
    

    是不是和原来的ClassA的构造器很像?更神奇的一点是,Dagger会自动搜索所需参数,然后在这里找@Provides同类型参数的函数,同样多个同类型的参数可以用@Named来解决。
    当然也可以不必这么麻烦,可以在构造ModuleA的时候new一个ClassA出来,到时候返回去。可见Dagger也是很有自由发挥空间的,只要把握几个要点就可以了。
    比如说Dagger生成的DaggerComponent其实可以不急于inject,而是需要的时候再inject。常见的就是在App初始化的时候生成一堆之后可能需要的DaggerComponent,然后等哪个地方需要就获取然后再注入。
    MainActivityClassAComponent并没有什么变化。

    生成代码

    生成代码没有太多变化,除了ClassA原来的构造器Dagger不知道了,现在用ModuleA_ProvideClassAFactory来代替:

    public final class ModuleA_ProvideClassAFactory implements Factory<ClassA> {
      private final ModuleA module;
    
      private final Provider<Integer> aProvider;
    
      private final Provider<Integer> bProvider;
    
      public ModuleA_ProvideClassAFactory(
          ModuleA module, Provider<Integer> aProvider, Provider<Integer> bProvider) {
        assert module != null;
        this.module = module;
        assert aProvider != null;
        this.aProvider = aProvider;
        assert bProvider != null;
        this.bProvider = bProvider;
      }
    
      @Override
      public ClassA get() {
        return Preconditions.checkNotNull(
            module.provideClassA(aProvider.get(), bProvider.get()),
            "Cannot return null from a non-@Nullable @Provides method");
      }
    
      public static Factory<ClassA> create(
          ModuleA module, Provider<Integer> aProvider, Provider<Integer> bProvider) {
        return new ModuleA_ProvideClassAFactory(module, aProvider, bProvider);
      }
    
      /** Proxies {@link ModuleA#provideClassA(int, int)}. */
      public static ClassA proxyProvideClassA(ModuleA instance, int a, int b) {
        return instance.provideClassA(a, b);
      }
    }
    

    生成的代码确实是“一个模子”里出来的。
    这里体现出封装的好处了:在无法直接调用构造器的情况下,使用Provider接口封装之后其余代码几乎没有什么区别。

    到目前为止,我们看到的只是很简单的依赖关系,那么交叉依赖又如何?例如ClassB需要ClassA与另一个整数a,而ClassA又依赖于a?Dagger是提供了很多方法来解决的,我们拭目以待吧。

    相关文章

      网友评论

        本文标题:Dagger 2学习与探索(四)

        本文链接:https://www.haomeiwen.com/subject/wbtddxtx.html