Dagger2 的模块化实现 以及常见问题总结

16 篇文章 0 订阅

简述

当我们在项目中使用Dagger2的时候,如果某个类 需要在项目的很多地方被引用到,比如UserInfo这个类,那么我们需要为它单独创建一个Module,来提供UserInfo的实例对象,
###代码描述
下面的这个类UserManager的构造方法中,需要传入UserInfo这个类实例对象, 而UserInfo就是我们需要在全局使用的类,它需要一个单独的Module来提供其实例对象。

/**
 * description:
 * author: dujun
 * created at: 2018/1/23 10:46
 * update: 2018/1/23
 * version:
 */
public class UserManager {

  private UserInfo userInfo;

    public UserManager(UserInfo userInfo){

        this.userInfo = userInfo;
    }

    public void test(){
        userInfo.test();
    }
 }

UserInfo类

/**
 * description: 
 * author: dujun
 * created at: 2018/1/23 10:51 
 * update: 2018/1/23
 * version: 
 */
public class UserInfo {

    public void test(){
        Log.d("dagger","UserInfo类");
    }
}

现在我们需要创建一个TestMododule来提供UserManager的实例对象

@Module
public class UserModule {
    
    @Provides
    public UserManager providerUserManager(UserInfo userInfo){
        return new UserManager(userInfo);
    }
}

正常来说,我们需要在下面再次创建一个providerUserInfo的方法来提供UserInfo对象,或者,我们在UserInfo的构造方法上面加上**@Inject注解,但是,如上面所说,UserInfo这个类,我们需要在项目的很多地方用到,那么,我们就得在每个用到Module里面,重复的去写providerUserInfo**这个方法。
所以,我们需要专门创建一个UserInfoModule。

/**
 * description: 
 * author: dujun
 * created at: 2018/1/23 10:52 
 * update: 2018/1/23
 * version: 
 */
@Module
public class UserInfoModule {
    @Provides
    public UserInfo provideUserInfo(){
        return new UserInfo();
    }
}

以上,我们就实现了Module的模块化,那么,我们怎样在UserModule中依赖到UserInfoModule呢,
其实,有三种方式:

方式1:在我们的UserComponet,直接通过‘,(逗号)’添加
/**
 * description: 
 * author: dujun
 * created at: 2018/1/23 11:03 
 * update: 2018/1/23
 * version: 
 */
@Component(modules = {UserModule.class,UserInfoModule.class})
public interface UserComponet {
    void inject(MainActivity mainActivity);
}
方式2:在Module使用 includes来依赖另一个Module

在UserModule中,通过includes来引入UserInfoModule

/**
 * description: 
 * author: dujun
 * created at: 2018/1/23 11:11 
 * update: 2018/1/23
 * version: 
 */
@Module(includes = {UserInfoModule.class})
public class UserModule {

    @Provides
    public UserManager providerUserManager(UserInfo userInfo){
        return new UserManager(userInfo);
    }
}
方式3:在Component中,使用dependencies来关联另一个Component

我们首先为UserInfoModule创建一个单独的Component

/**
 * description:
 * author: dujun
 * created at: 2018/1/23 11:05 
 * update: 2018/1/23
 * version: 
 */
@Component(modules = UserInfoModule.class)
public class UserInfoComponent {

}

然后,通过在UserComponet 中通过dependencies 来关联

/**
 * description: 
 * author: dujun
 * created at: 2018/1/23 11:03 
 * update: 2018/1/23
 * version: 
 */
@Component(modules = {UserModule.class},dependencies = UserInfoComponent.class)
public interface UserComponet {
    void inject(MainActivity mainActivity);
}

最后rebuild, 注入即可

  DaggerUserComponet.builder()
                .userModule(new UserModule())
                .userInfoModule(new UserInfoModule())
                .build()
                .inject(this);

Dagger2中的一些常见问题总结

  • componet 的 inject 方法接收父类型参数,而调用时传入的是子类型对象则无法注入
  • component关联的modules中不能有重复的provide
  • module 的 provide 方法使用了 scope ,那么 component 就必须使用同一个注解
  • module 的 provide 方法没有使用 scope ,那么 component 和 module 是否加注解都无关紧要,可以通过编译
  • component的dependencies与component自身的scope不能相同,即组件之间的scope不同
  • Singleton的组件不能依赖其他scope的组件,只能其他scope的组件依赖Singleton的组件
  • 没有scope的component不能依赖有scope的component
  • 一个component不能同时有多个scope(Subcomponent除外)
  • @Singleton 的生命周期依附于component,同一个module provide singleton ,不同component 也是不一样

追加

下面是一个AppModule:,这个AppComponent的作用让别的Component依赖这个Component,而自己不注入到任何类中。

public class AppModule {

    private Application application;
    public AppModule(Application application) {
        this.application = application;
    }

    @Provides
    @Singleton
    public Application provideApplication(){
        return application;
    }


    @Provides
    @Singleton
    public Gson provideGson(){
        return new Gson();
    }
}

如下是一个AppComponent:

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    // 注意:这俩个方法是可以不用写的,但是,如果你想让别的Component依赖这个Component,
    // 就必须写,不写这个方法,就意味着没有向外界暴漏这个依赖
    ApiService getApiService();
    Gson getGson();
    //这里App并没有想注入到那个类中,可以不写inject方法
    //  void inject(Object o);
}

具体看以上代码中注释

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值