Dagger2 中的 Scope、dependencies

Scope中文意思是范围,Dagger2 中的@Singleton是 Scope 的一种默认实现,点进去可以看到:

@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}

上面是 Java 方式,如果我们自定义一个 Scope 就很简单了(kotlin 语言):

@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
annotation class ZhuangBiScope

一个 Component 依赖另一个 Component 时需要用到 Scope,至于为什么 Component 之间要互相依赖,简单说下:一个项目里有很多功能模块,很多的 Activity,每个 Activity 都有对应的 Component,那么每个 Component 再对应多个 Module,最终工程会很庞大。有些 Module 可以共用,所以就需要dependencies关键字来依赖别的 Component。

比如 AnimalComponent 要依赖 BComponent

AnimalComponent.kt

@ZhuangBiScope
@Component(dependencies = [(BComponent::class)],modules = [(AppModule::class), (AnimalModule::class)])
interface AnimalComponent {
    fun inject(secondActivity: SecondActivity)
}

AnimalComponent 需要依赖 BComponent,则@ZhuangBiScope注解在 AnimalComponent 上面。另外,AnimalComponent 包含的 AppModule 和 AnimalModule 里面的provideXX()方法要么不用任何 Scope 注解,要么用@ZhuangBiScope注解,不可以用@Singleton注解。

AppModule.kt

@Module
class AppModule(var myApp: Application) {
    @Provides
    @ZhuangBiScope
    fun providesApplication(): Application = myApp
}

AnimalModule.kt

@Module
class AnimalModule {
    @Provides
    @ZhuangBiScope
    fun providesDog(): Dog {
        Log.e("abc", "----- AnimalModule Dog -----")
        return Dog()
    }

    @Provides
    @Tested("dog")
    @ZhuangBiScope
    fun providesCat(dog: Dog): Cat {
        Log.e("abc", "----- AnimalModule Cat withdog -----")
        return Cat(dog)
    }

    @Provides
    @Tested("dog2")
    fun providesCat2(dog: Dog): Cat {
        Log.e("abc", "----- AnimalModule Cat withdog2 -----")
        return Cat(dog)
    }
}

上面的 providesCat2() 方法没有任何 Scope 注解。
接下来我们看看 BComponent:

@Singleton
@Component(modules = [(PersonModule::class), (StudentModule::class)])
interface BComponent {
    fun inject(bActivity: BActivity)
    fun person(): Person
    fun provideStudent(): Student
//    fun test(): String//会报错
}

包含两个 Module,一开始我只写了第一行的fun inject(bActivity: BActivity)结果总是报错,在这里卡了很久。需要说明的是:

当一个 Component 给别的 Component 依赖时,被依赖的 Component 要定义一些方法。这些方法的返回值类型和它包含的 Module 中方法返回类型相同。

举例说明,BComponent 包含 PersonModule 和 StudentModule,两者分别包含:

@Singleton
@Provides
fun providePerson(): Person = Person()

@Provides
fun provideStudent(): Student = Student()

当 AnimalComponent 所 inject 的类中需要用到上面这两个实例的时候,就需要在 BComponent 中注册两个方法给 inject 的类使用(方法名叫什么都无所谓):

fun person(): Person
fun provideStudent(): Student

另外,BComponent 中不可以定义其他方法,否则也会报错。

你可能感兴趣的:(Dagger2 中的 Scope、dependencies)