我可以自由地将示例更改为:a)删除不必要的细节,b)简化设置。
给出3个具有以下类别的模块:
// ----->> app <<-----class App @Inject constructor( private val api: AbstractApi, private val argParser: ArgParser)// ----->> google <<-----// expose a public interfaceinterface AbstractApi// have our internal implementationinternal class GoogleApi @Inject constructor( private val argParser: ArgParser) : AbstractApi// ----->> common <<-----// expose some common classinterface ArgParser
因此,我们需要绑定一个实现了
ArgParser两个
app。我
ArgParser在这里以示例为例,说明如何将参数传递给API。
GoogleApi完全
internal确保没有泄漏。我们只公开接口
AbstractApi。
我通过GoogleApi
内部实现来消除实现/
API的Gradle复杂性。行为是相同的,甚至可能更严格:我们的模块中有一些我们无法公开的类。这样,我们也可以进行编译器验证。
我们可以将所有实现细节都隐藏在添加的组件后面,以添加组件
GoogleApi接口的实现。
// ----->> google@Component(modules = [ApiModules::class])interface ApiComponent { // has a provision method for our API fun api(): AbstractApi @Component.Factory interface Factory { // factory method to bind additional args that we need to supply fun create(@BindsInstance parser: ArgParser): ApiComponent }}@Moduleinternal interface ApiModules { @Binds fun bindApi(googleApi: GoogleApi): AbstractApi}我们在这里不使用范围,因为应该在使用此组件的任何地方处理范围。
ArgParser是我们可能需要提供以创建对象的参数的示例。我们也可以使用a
@Component.Builder代替工厂。
Dagger将在同一模块(
app模块中检索API :
// ----->> app@Component(modules = [AppModule::class])interface AppComponent { fun app(): App}@Moduleclass AppModule { @Provides fun provideParser(): ArgParser = object : ArgParser {} // just bind a dummy implementation @Provides fun provideApi(argParser: ArgParser): AbstractApi { return DaggerApiComponent.factory().create(argParser).api() }}现在,我们可以使用组件工厂从模块中创建实例。如果我们需要一个范围,我们可以像往常一样在
@Provides方法上添加它。
此设置应完全隐藏
app公共接口后面模块中的所有细节。生成的代码位于同一模块内。
为什么不公开@Module
?一个@Subcomponent
?
据报道,将模块添加到组件中也会在该组件内生成工厂代码,这将尝试使用未引用的类。子组件也是如此。
为什么不使用组件依赖关系?
由于组件上没有作用域,因此我们最好将其添加为组件依赖项,但那时我们将无法添加作用域。另外,传递参数会很麻烦,因为在创建组件时必须提供参数。



