@IntoMap @Binds 到底如何与 Dagger 配合使用?

Dav*_*vid 3 java android kotlin dagger-2

我正在使用Dagger并且我想要@inject一个Repository我的ViewModel所以我创建一个抽象模块,其中包含Map存储库类:

我的抽象模块:

@Module
abstract class RepositoryModule{

    @Binds
    @IntoMap
    @ClassKey(RepositoryStatus::class)
    abstract fun provideRepositoryStatus(repositoryStatus: RepositoryStatus): RepositoryStatus
}
Run Code Online (Sandbox Code Playgroud)

我的ViewModel模块包括RespositoryModule

@Module(includes = [
    RepositoryModule::class
])
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(MainViewModel::class)
    abstract fun bindsMainViewModel(viewModel: MainViewModel): ViewModel
}
Run Code Online (Sandbox Code Playgroud)

我不知道它到底是如何工作的,Dagger 如何知道我有一张地图并且我将它与我的绑定ViewModel?因为我从来没有使用过这个方法。我在图表中包含了一张地图,因此我认为除非我调用它,否则它无法使用。

cor*_*her 9

@Binds与 类似@Provides,只是它用于提供接口、抽象类或在您的情况下扩展的类。所以不需要任何配置,也不@Provides需要调用。

虽然@IntoMap用作将您的键放入映射的命令put,其中键由@ClassKey@ViewModelKey在您的情况下提供,值由 提供@Binds

另请检查文档,因为我的解释是针对您的具体情况的。但这是基本的。来自 Daggers Javadoc:

@Binds

注释委托绑定的模块的抽象方法。例如,要将 Random 绑定到 SecureRandom,模块可以声明以下内容: @Binds abstract Random bindRandom(SecureRandom secureRandom); @Binds 方法是只返回注入参数的 Provides 方法的直接替代。更喜欢@Binds,因为生成的实现可能更高效。

@IntoMap

该方法的返回类型形成 Map> 值的类型参数,并且带注释的键和返回值的组合作为键/值对贡献给映射。值的积累产生的Map>将是不可变的。

  • 可以这样想,您给我 5 个银行帐户,并为每个帐户提供密码。我是匕首,我把你的账户和密码放在地图上。当您请求帐号 1 时,我会询问密码,如果正确,我就会给您。 (5认同)
  • “地图”是数据结构,而不是模式。 (3认同)
  • 你没有得到地图,你只是指示dagger将它们放入地图中。之后,正确的依赖项来自“@Inject”,是的。 (2认同)