Dagger组件化

前言:清楚dagger定义的层次也就实现了组件化。例如需要注入Application、Activity、LifecycleProvider参数,这些参数在基础库lib_base里定义,而由于inject()需要注入到具体的activity或fragment中,因此需要在上层业务库lib_use中定义。
实现:
一、注入Application

1、定义数据源

@Module
class AppModule(private val context: Application) {

    @Provides
    @Singleton
    fun providesContext(): Context {
        return context
    }
}

2、定义数据组织者

@Singleton
@Component(modules = arrayOf(AppModule::class))
interface AppComponent {

    fun context(): Context
}

3、在lib_base中的BaseApplication中生成Application数据组织者

open class BaseApplication : MultiDexApplication() {

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        appComponent = DaggerAppComponent.builder()
                .appModule(AppModule(this))
                .build()
    }
}

二、注入Activity、LifecycleProvider
1、定义Activity数据源

@Module
class ActivityModule(private val activity: Activity) {

    @ActivityScope
    @Provides
    fun providesActivity(): Activity {
        return activity
    }
}

2、定义LifecycleProvider数据源

@Module
class LifecycleProviderModule(private val lifecycleProvider: LifecycleProvider<*>) {

    @Provides
    fun provideLifecycleProvider(): LifecycleProvider<*> {
        return this.lifecycleProvider
    }
}

3、定义Activity和LifecycleProvider组织者

@ActivityScope
@Component(dependencies = arrayOf(AppComponent::class), modules = arrayOf(ActivityModule::class, LifecycleProviderModule::class))
interface ActivityComponent {

    fun context(): Context
    fun activity(): Activity
    fun lifecycleProvider(): LifecycleProvider<*>

}

4、定义区间注解(下面详解)

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerComponentScope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class ActivityScope

5、在lib_base中的Activity基类中生成Activity、LifecycleProvider数据组织者

abstract class BaseMvpActivity<T : BasePresenter<*>> : BaseActivity(), BaseView {

    @Inject
    lateinit var mPresenter: T

    lateinit var mActivityComponent: ActivityComponent
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initInjection()
    }

    private fun initInjection() {
        mActivityComponent = DaggerActivityComponent.builder()
            .appComponent((application as BaseApplication).appComponent)
            .activityModule(ActivityModule(this))
            .lifecycleProviderModule(LifecycleProviderModule(this))
            .build()
        injectComponent()
    }

    protected abstract fun injectComponent()
}

三、在业务层注入依赖

1、定义数据组织者

@PerComponentScope
@Component(dependencies = arrayOf(ActivityComponent::class))
interface UserComponent {
    fun inject(activity: LoginActivity)
}

2、生成数据组织者并注入依赖

class LoginActivity : BaseMvpActivity<LoginPresenter>(), LoginView{

    override fun injectComponent() {
        DaggerUserComponent.builder()
            .activityComponent(mActivityComponent)
            .build()
            .inject(this)
        mPresenter.mView = this
    }
}

四、讲解一下@Scope自定义区间

1、区间是与组织者Component相关联的,意义是针对同一个组织者注入的数据源为单例。例如需要注入Test对象,数据源是通过new提供的而非上文构造传参方式,在LoginActivity中注入testOne: Test和testTwo: Test则testOne和testTwo为两个对象,而使用自定义区间后则testOne和testTwo为同一对象。如在RegistActivity中注入test:Test则和LoginActivity中注入的非同一个对象,毕竟UserComponent非同一对象。

2、@Singleton为Dagger预定义的Scope

3、自定义区间名称可以任意,区间本身并不能定义单例区间大小,是由Component对象决定的,@Singl同理。

4、全局单例则将Component全局唯一,如在application中生成的AppComponent对象则保证了提供的数据源全局唯一

五、总结

在业务层定义新activity时,需在业务层Component中添加inject(activity: 自定义activity),然后重写该activity的injectComponent方法可以直接拷贝步骤三的2中代码,注意由于inject()必须指定注入到具体Activity类,所以无法将injectComponent方法在基类activity中进行实现,以至于每新建activity需要进行上面两步操作。

猜你喜欢

转载自blog.csdn.net/yufumatou/article/details/111042751