Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Demystifying Dagger

Demystifying Dagger

Dagger gets a bad rap for being "difficult to understand", or "overly complicated", or "black magic". In reality, Dagger generates pretty straight-forward, elegant wiring code similar to how we would likely write it manually and, I believe, it's the complexity of large scale apps that makes it complex.

In this talk we'll look at different types of injection that Dagger supports, and the code it generates to do so, to get an understanding of what it's doing and how it works. We'll then dive into Components and Subcomponents to see how Dagger wires together our dependencies into a graph. Finally, we'll look at how Dagger can be extended using Anvil and other tools.

Ryan Harter

October 27, 2023
Tweet

More Decks by Ryan Harter

Other Decks in Programming

Transcript

  1. Dependency Injection 🗡 class CrashReporter Property("awesome") Backend(token = "abc123") private

    val userProp: Property private val backend: Backend = = { / / . .. }
  2. Dependency Injection 🗡 class CrashReporter private val userProp: Property private

    val backend: Backend = = { / / . .. } MyDependencies.property MyDependencies.backend
  3. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) { // . .. } @Inject constructor userProp: Property backend: Backend Constructor Injection 🗡
  4. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) { } @Inject constructor Constructor Injection 🗡
  5. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) { } @Inject constructor userProp: Property backend: Backend Constructor Injection 🗡
  6. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) { // . .. } @Inject constructor userProp: Property backend: Backend Constructor Injection 🗡
  7. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory userPropProvider: Provider<Property> backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  8. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory userPropProvider: Provider<Property> backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  9. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory userPropProvider: Provider<Property> backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  10. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory userPropProvider: Provider<Property> backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  11. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  12. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  13. class CrashReporter_Factory( private val userPropProvider: Provider<Property>, private val backendProvider: Provider<Backend>,

    ) : Provider<CrashReporter> { override fun get(): CrashReporter { return CrashReporter( userPropProvider.get(), backendProvider.get(), ) } } CrashReporter_Factory userPropProvider: Provider<Property> backendProvider: Provider<Backend> Provider<CrashReporter> override fun get(): CrashReporter CrashReporter( userPropProvider.get(), backendProvider.get(), ) Constructor Injection 🗡
  14. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  15. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  16. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  17. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  18. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  19. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  20. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  21. class MyFragment_MembersInjector( private val crashReporterProvider: Provider<CrashReporter>, ) : MembersInjector<MyFragment> {

    override fun injectMembers(instance: MyFragment) { instance.crashReporter = crashReporterProvider.get() } } MyFragment_MembersInjector MembersInjector<MyFragment> private val crashReporterProvider: Provider<CrashReporter> override fun injectMembers(instance: MyFragment) instance.crashReporter = crashReporterProvider.get() Member Injection 🗡
  22. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  23. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  24. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  25. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  26. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  27. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  28. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  29. @Module class CrashModule { @Provides fun provideBackend(token: ApiToken): Backend {

    return Backend(token) } } @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) Provider Injection 🗡
  30. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract Provider Injection 🗡
  31. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract Provider Injection 🗡
  32. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract @Binds Provider Injection 🗡
  33. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract @Binds abstract fun bindService() Provider Injection 🗡
  34. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract @Binds abstract fun bindService(backend: Backend) Provider Injection 🗡
  35. @Module @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) :

    { } class CrashModule { abstract @Binds abstract fun bindService(backend: Backend): Service Provider Injection 🗡
  36. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  37. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  38. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  39. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  40. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  41. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  42. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  43. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  44. { { CrashModule_ProvideBackendFactory ) } } class ( private val

    module: CrashModule, , private val tokenProvider: Provider<ApiToken> Provider<Backend?> : override fun get(): Backend return module.provideBackend( ) tokenProvider.get() Provider Injection 🗡
  45. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) class MyFragment : Fragment() { @Inject lateinit var crashReporter: CrashReporter } Property Backend CrashReporter Qualifiers 🗡
  46. class CrashReporter @Inject constructor( private val userProp: Property, private val

    backend: Backend, ) class MyFragment : Fragment() { @Inject lateinit var crashReporter: CrashReporter } Property Backend CrashReporter Qualifiers 🗡
  47. private val backend: Backend, ) @Module class CrashModule { @Provides

    fun provideBackend(token: ApiToken): Backend { return Backend(token) } } class MyFragment : Fragment() { @Inject lateinit var crashReporter: CrashReporter } Backend CrashReporter Backend Qualifiers 🗡
  48. private val backend: Backend, ) @Module class CrashModule { @Provides

    fun provideBackend(token: ApiToken): Backend { return Backend(token) } } class MyFragment : Fragment() { @Inject lateinit var crashReporter: CrashReporter } Backend CrashReporter Backend Qualifiers 🗡
  49. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { ApiToken String Qualifiers 🗡 fun provideBackend(token:
  50. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { ApiToken String Qualifiers 🗡 fun provideBackend(token:
  51. @Module class CrashModule { } @Provides return Backend(token) } String

    Qualifiers 🗡 fun provideBackend(token: ): Backend {
  52. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { fun provideBackend( String @Provides fun provideApiToken(): String = "abcd" token: Qualifiers 🗡
  53. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { String @Provides fun provideApiToken(): String = "abcd" fun provideBackend(token: Qualifiers 🗡
  54. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { String @Provides fun provideApiToken(): String = "abcd" @ApiToken fun provideBackend( token: @ApiToken Qualifiers 🗡
  55. @Module class CrashModule { } @Provides return Backend(token) } ):

    Backend { String @Provides fun provideApiToken(): String = "abcd" @ApiToken fun provideBackend( token: @ApiToken Qualifiers 🗡
  56. class DaggerAppComponent { DaggerAppComponent companion object { fun builder(): Builder

    { // .. . } } class Builder { // ... fun build(): AppComponent { // .. . } } private class AppComponentImpl : AppComponent { // .
  57. class DaggerAppComponent { DaggerAppComponent companion object { fun builder(): Builder

    { } } class Builder { fun build(): AppComponent { } } private class AppComponentImpl : AppComponent { .
  58. class DaggerAppComponent { DaggerAppComponent companion object { fun builder(): Builder

    { // .. . } } class Builder { // ... fun build(): AppComponent { // .. . } } private class AppComponentImpl : AppComponent { .
  59. class DaggerAppComponent { DaggerAppComponent companion object { fun builder(): Builder

    { } } class Builder { fun build(): AppComponent { } } private class AppComponentImpl : AppComponent { private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> } } / / . ..
  60. class DaggerAppComponent { DaggerAppComponent private class AppComponentImpl : AppComponent {

    private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> } } .
  61. class DaggerAppComponent { DaggerAppComponent private class AppComponentImpl : AppComponent {

    // Providers private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> // MembersInjectors private val myFragmentMembersInjector: MembersInjector<MyFragment> } } .
  62. class DaggerAppComponent { DaggerAppComponent private class AppComponentImpl : AppComponent {

    // Providers private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> // MembersInjectors private val myFragmentMembersInjector: MembersInjector<MyFragment> } } .
  63. class DaggerAppComponent { DaggerAppComponent private class AppComponentImpl : AppComponent {

    private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> } } . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) }
  64. class DaggerAppComponent { DaggerAppComponent private class AppComponentImpl : AppComponent {

    // Providers private val userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> // MembersInjectors private val myFragmentMembersInjector: MembersInjector<MyFragment> } } . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) }
  65. private class AppComponentImpl : AppComponent { private val userPropProvider: Provider<Property>

    private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> } } . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) } override val crashReporter: CrashReporter get() = crashReporterProvider.get()
  66. @Component(modules = [CrashModule :: class]) interface AppComponent { } fun

    inject(instance: MyFragment) val crashReporter: CrashReporter
  67. @Component(modules = [CrashModule interface AppComponent { } fun inject(instance: MyFragment)

    val crashReporter: CrashReporter @AppScope @Module interface CrashModule { @Binds } fun bindCrashReporter(impl: RealCrashReporter): CrashReporter @AppScope
  68. @Component(modules = [CrashModule interface AppComponent { } fun inject(instance: MyFragment)

    val crashReporter: CrashReporter @AppScope @Module interface CrashModule { @Binds } fun bindCrashReporter(impl: RealCrashReporter): CrashReporter @AppScope
  69. class ScopedProvider<T>( ) : Provider<T> { override fun get(): T

    { return instance } } private val implProvider: Provider<T> private var instance: T? = null if (instance = = null) { instance = implProvider.get() }
  70. class ScopedProvider<T>( ) : Provider<T> { override fun get(): T

    { return instance } } private val implProvider: Provider<T> private var instance: T? = null if (instance instance = implProvider.get() }
  71. class ScopedProvider<T>( ) : Provider<T> { override fun get(): T

    { return instance } } private val implProvider: Provider<T> private var instance: T? = null if (instance instance = implProvider.get() }
  72. class ScopedProvider<T>( ) : Provider<T> { override fun get(): T

    { return instance } } private val implProvider: Provider<T> private var instance: T? = null if (instance = = null) { instance = implProvider.get() }
  73. private class AppComponentImpl : AppComponent { // Providers private val

    userPropProvider: Provider<Property> private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> // MembersInjectors private val myFragmentMembersInjector: MembersInjector<MyFragment> } } . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) } override val crashReporter: CrashReporter get() = crashReporterProvider.get()
  74. private class AppComponentImpl : AppComponent { private val userPropProvider: Provider<Property>

    private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) } init( // . .. , crashReporterProvider: Provider<CrashReporter>, ) { // . .. this.crashReporterProvider = } crashReporterProvider
  75. private class AppComponentImpl : AppComponent { private val userPropProvider: Provider<Property>

    private val backendProvider: Provider<Backend> private val tokenProvider: Provider<ApiToken> private val crashReporterProvider: Provider<CrashReporter> private val myFragmentMembersInjector: MembersInjector<MyFragment> . override fun inject(instance: MyFragment) { myFragmentMembersInjector.injectMembers(instance) } init( // . .. , crashReporterProvider: Provider<CrashReporter>, ) { // . .. this.crashReporterProvider = } ScopedProvider(crashReporterProvider) crashReporterProvider
  76. { } fun inject(instance: MyFragment) fun inject(instance: ListActivity) fun inject(instance:

    ItemListFragment) fun inject(instance: ItemDetailFragment) fun inject(instance: ShareFragment) fun inject(instance: AccountActivity) fun inject(instance: FriendsFragment) fun inject(instance: SettingsActivity) @Component(modules = [CrashModule :: class]) interface AppComponent ⚒
  77. { } fun inject(instance: MyFragment) fun inject(instance: ListActivity) fun inject(instance:

    ItemListFragment) fun inject(instance: ItemDetailFragment) fun inject(instance: ShareFragment) fun inject(instance: AccountActivity) fun inject(instance: FriendsFragment) fun inject(instance: SettingsActivity) @Component(modules = [ CrashModule :: class ]) interface AppComponent , AnalyticsModule :: class, NetworkModule : : class BillingModule : : class DatabaseModule :: class FileModule :: class UserModule :: class , , , , , ⚒
  78. @Component(modules = [ CrashModule :: class ]) interface AppComponent ,

    AnalyticsModule :: class, NetworkModule : : class BillingModule : : class DatabaseModule :: class FileModule :: class UserModule :: class , , , , , ⚒ : MyFragmentInjector, ListActivityInjector, ItemListFragmentInjector, ItemDetailFragmentInjector, ShareFragmentInjector, AccountActivityInjector, FriendsFragmentInjector, SettingsActivityInjector,
  79. ⚒ abstract class AppObjectGraph interface MyFragmentInjector { fun inject(instance: MyFragment)

    } @ContributesTo(AppObjectGraph : @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) : { }
  80. ⚒ abstract class AppObjectGraph interface MyFragmentInjector { fun inject(instance: MyFragment)

    } @ContributesTo(AppObjectGraph : @Module class CrashModule { @Provides } fun provideBackend(token: ApiToken) Backend return Backend(token) : { } @ContributesTo(AppObjectGraph :: class)
  81. @Component(modules = [ CrashModule :: class ]) interface AppComponent ,

    AnalyticsModule :: class, NetworkModule : : class BillingModule : : class DatabaseModule :: class FileModule :: class UserModule :: class , , , , , ⚒ : MyFragmentInjector, ListActivityInjector, ItemListFragmentInjector, ItemDetailFragmentInjector, ShareFragmentInjector, AccountActivityInjector, FriendsFragmentInjector, SettingsActivityInjector, @MergeComponent(scope = AppObjectGraph :
  82. ⚒ @Module interface CrashModule { @Binds } fun bindCrashReporter(impl: RealCrashReporter):

    CrashReporter @ContributesTo(AppObjectGraph :: class) class RealCrashReporter @Inject constructor( private val userProp: Property, private val backend: Backend, ): CrashReporter { // . .. }
  83. ⚒ class RealCrashReporter @Inject constructor( private val userProp: Property, private

    val backend: Backend, ): CrashReporter { } @ContributesBinding(AppObjectGraph :: class)