Helping Dagger Help You (Droidcon UK 2018)

Helping Dagger Help You (Droidcon UK 2018)

As applications grow in size, Dagger can help mitigate the pain of dependency management and eliminate the boilerplate of manual dependency injection. Despite this, there are still pain points such as slower compilation times and how to inject objects like activities and views. This talk will cover functionality provided by libraries which build on top of Dagger to reduce these pain points. We'll learn what assisted injection is, why you might use it, and look at a library which simplifies the pattern. And finally we'll attempt to solve the build speed problem so that development builds are as fast as possible without sacrificing Dagger's compile-time safety.

Video: http://uk.droidcon.com/skillscasts/11617-helping-dagger-help-you

E68309f117985270285ade8082f4877d?s=128

Jake Wharton

October 26, 2018
Tweet

Transcript

  1. Helping Dagger Help You @JakeWharton

  2. boilerplate /ˈbɔɪləpleɪt/ noun standardized pieces of text for use as

    clauses in contracts or as part of a computer program
  3. verbosity /vəˈbɒsɪti/ noun the fact or quality of using more

    words than needed; wordiness
  4. None
  5. None
  6. Dagger

  7. Dagger

  8. Service Locator

  9. Manual Dependency Injection

  10. Manual Dependency Injection

  11. Manual Dependency Injection

  12. Service Locator

  13. Dagger

  14. Dagger

  15. Dagger

  16. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { // … }Y
  17. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { // which profile do we load? }Y
  18. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { // which profile do we load? // what initials do we render the avatar placeholder with? }Y
  19. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { // which profile do we load? // what initials do we render the avatar placeholder with? // which image url do we download? }Y
  20. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { lateinit var userId: String // which profile do we load? // what initials do we render the avatar placeholder with? // which image url do we download? }Y
  21. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { lateinit var userId: String // which profile do we load? // what initials do we render the avatar placeholder with? // which image url do we download? }Y var userId: String = …
  22. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { lateinit var userId: String // which profile do we load? // what initials do we render the avatar placeholder with? // which image url do we download? }Y var userId: String = … presenter.userId = userId
  23. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { lateinit var userId: String // which profile do we load? // what initials do we render the avatar placeholder with? // which image url do we download? }Y var userId: String = … presenter.userId = userId // Use presenter…
  24. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer ) { lateinit var userId: String // … }Y var userId: String = … presenter.userId = userId // Use presenter…
  25. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y var userId: String = … presenter.userId = userId // Use presenter…
  26. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y // Use presenter…
  27. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y // Use presenter…
  28. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @UserId var userId: String ) { // … }Y // Use presenter…
  29. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y // Use presenter…
  30. class ProfilePresenter @Inject constructor(A val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y
  31. class ProfilePresenter(A val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … }Y
  32. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory }Y
  33. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer: AvatarRenderer )G }Y
  34. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer: AvatarRenderer )G{ fun create(userId: String) }Z }Y
  35. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer: AvatarRenderer )G{ fun create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y
  36. class ProfilePresenter(…) { // … class Factory @Inject constructor(…)G{ fun

    create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y
  37. class ProfilePresenter(…) { // … class Factory @Inject constructor(…) {

    fun create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y var userId: String = …
  38. class ProfilePresenter(…) { // … class Factory @Inject constructor(…) {

    fun create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y var userId: String = … val presenter = presenterFactory.create(userId) // Use presenter…
  39. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer: AvatarRenderer ) { fun create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y
  40. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: ImageLoader, val profilePersistence:<ProfilePersistence, val avatarRenderer: AvatarRenderer ) { fun create(userId: String) = ProfilePresenter(imageLoader, profilePersistence, avatarRenderer, userId) }Z }Y
  41. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  42. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  43. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  44. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  45. class ProfilePresenter { private final ImageLoader imageLoader; private final ProfilePersistence

    profilePersistence; private final AvatarRenderer avatarRenderer; private final String userId; ProfilePresenter( ImageLoader imageLoader, ProfilePersistence profilePersistence, AvatarRenderer avatarRenderer, String userId) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; this.userId = userId; }A // … static final class Factory { private final Provider<ImageLoader> imageLoader;
  46. // … static final class Factory { private final Provider<ImageLoader>

    imageLoader; private final Provider<ProfilePersistence> profilePersistence; private final Provider<AvatarRenderer> avatarRenderer; @Inject Factory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; }B public ProfilePresenter create(String userId) { return new ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId); }C }D }E
  47. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> )G{ fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y i n t e r f a c e
  48. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … interface FactoryG{ fun create(userId: String): ProfilePresenter }Z }Y
  49. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … interface Factory { fun create(userId: String): ProfilePresenter }Z }Y install(FactoryModuleBuilder() .build(ProfilePresenter::class.java))
  50. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … interface Factory { fun create(userId: String): ProfilePresenter }Z }Y install(FactoryModuleBuilder() .build(ProfilePresenter::class.java))
  51. class ProfilePresenter @Inject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … interface Factory { fun create(userId: String): ProfilePresenter }Z }Y install(FactoryModuleBuilder() .build(ProfilePresenter::class.java))
  52. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  53. @AutoFactory class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val

    avatarRenderer: AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> ) { fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y
  54. @AutoFactory class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val

    avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y
  55. @AutoFactory class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val

    avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y @Generated final class ProfilePresenterFactory { @Inject ProfilePresenterFactory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { … } ProfilePresenter create(userId: String) { … } }Z
  56. @AutoFactory class ProfilePresenter( @Provided val imageLoader: ImageLoader, @Provided val profilePersistence:

    ProfilePersistence, @Provided val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y @Generated final class ProfilePresenterFactory { @Inject ProfilePresenterFactory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { … } ProfilePresenter create(userId: String) { … } }Z
  57. @AutoFactory class ProfilePresenter( @Provided val imageLoader: ImageLoader, @Provided val profilePersistence:

    ProfilePersistence, @Provided val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y @Generated final class ProfilePresenterFactory { @Inject ProfilePresenterFactory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { … } ProfilePresenter create(userId: String) { … } }Z
  58. @AutoFactory class ProfilePresenter( @Provided val imageLoader: ImageLoader, @Provided val profilePersistence:

    ProfilePersistence, @Provided val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y @Generated final class ProfilePresenterFactory { @Inject ProfilePresenterFactory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { … } ProfilePresenter create(userId: String) { … } }Z
  59. @AutoFactory class ProfilePresenter( @Provided val imageLoader: ImageLoader, @Provided val profilePersistence:

    ProfilePersistence, @Provided val avatarRenderer: AvatarRenderer, var userId: String ) { // … }Y @Generated final class ProfilePresenterFactory { @Inject ProfilePresenterFactory(Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { … } ProfilePresenter create(userId: String) { … } }Z
  60. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … class Factory @Inject constructor( val imageLoader: Provider<ImageLoader>, val profilePersistence: Provider<ProfilePersistence>, val avatarRenderer: Provider<AvatarRenderer> )G{ fun create(userId: String) = ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId) }Z }Y i n t e r f a c e
  61. class ProfilePresenter( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence, val avatarRenderer:

    AvatarRenderer, var userId: String ) { // … interface FactoryG{ fun create(userId: String): ProfilePresenter }Z }Y
  62. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, var userId: String ) { // … interface FactoryG{ fun create(userId: String): ProfilePresenter }Z }Y
  63. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … interface FactoryG{ fun create(userId: String): ProfilePresenter }Z }Y
  64. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … @AssistedInject.Factory interface FactoryG{ fun create(userId: String): ProfilePresenter }Z }Y
  65. @Generated class AssistedInject_ProfilePresenter implements ProfilePresenter.Factory { private final Provider<ImageLoader> imageLoader;

    private final Provider<ProfilePersistence> profilePersistence; private final Provider<AvatarRenderer> avatarRenderer; @Inject AssistedInject_ProfilePresenter( Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; } @Override public ProfilePresenter create(String userId) { return new ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId); } }
  66. @Generated class AssistedInject_ProfilePresenter implements ProfilePresenter.Factory { private final Provider<ImageLoader> imageLoader;

    private final Provider<ProfilePersistence> profilePersistence; private final Provider<AvatarRenderer> avatarRenderer; @Inject AssistedInject_ProfilePresenter( Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; } @Override public ProfilePresenter create(String userId) { return new ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId); } }
  67. @Generated class AssistedInject_ProfilePresenter implements ProfilePresenter.Factory { private final Provider<ImageLoader> imageLoader;

    private final Provider<ProfilePersistence> profilePersistence; private final Provider<AvatarRenderer> avatarRenderer; @Inject AssistedInject_ProfilePresenter( Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; } @Override public ProfilePresenter create(String userId) { return new ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId); } }
  68. @Generated class AssistedInject_ProfilePresenter implements ProfilePresenter.Factory { private final Provider<ImageLoader> imageLoader;

    private final Provider<ProfilePersistence> profilePersistence; private final Provider<AvatarRenderer> avatarRenderer; @Inject AssistedInject_ProfilePresenter( Provider<ImageLoader> imageLoader, Provider<ProfilePersistence> profilePersistence, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.profilePersistence = profilePersistence; this.avatarRenderer = avatarRenderer; } @Override public ProfilePresenter create(String userId) { return new ProfilePresenter(imageLoader.get(), profilePersistence.get(), avatarRenderer.get(), userId); } }
  69. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … @AssistedInject.Factory interface Factory { fun create(userId: String): ProfilePresenter }Z }Y
  70. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … @AssistedInject.Factory interface Factory { fun create(userId: String): ProfilePresenter }Z }Y
  71. class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val profilePersistence: ProfilePersistence,

    val avatarRenderer: AvatarRenderer, @Assisted var userId: String ) { // … @AssistedInject.Factory interface Factory { fun create(userId: String): ProfilePresenter }Z }Y class AssistedInject_ProfilePresenter implements ProfilePresenter.Factory { @Inject AssistedInject_ProfilePresenter(…) }
  72. @Module abstract class AssistedModule { }S

  73. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S
  74. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S
  75. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S
  76. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S
  77. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S @Component(modules = [PresenterModule::class]) interface PresenterComponent { // … }T
  78. @Module abstract class AssistedModule { @Binds abstract fun bindProfilePresenterFactory( factory:

    AssistedInject_ProfilePresenter): ProfilePresenter.Factory }S @Component(modules = [PresenterModule::class, AssistedModule::class]) interface PresenterComponent { // … }T
  79. @Module object PresenterModule { @JvmStatic @Provides fun thing() = Thing("API

    key") }H
  80. @AssistedModule @Module object PresenterModule { @JvmStatic @Provides fun thing() =

    Thing("API key") }H
  81. @AssistedModule @Module object PresenterModule { @JvmStatic @Provides fun thing() =

    Thing("API key") }H @Module @Generated abstract class AssistedModule_PresenterModule { @Binds abstract ProfilePresenter.Factory bindProfilePresenterFactory( AssistedInject_ProfilePresenter factory) }S
  82. @AssistedModule @Module(includes = [AssistedModule_PresenterModule::class]) object PresenterModule { @JvmStatic @Provides fun

    thing() = Thing("API key") }H @Module @Generated abstract class AssistedModule_PresenterModule { @Binds abstract ProfilePresenter.Factory bindProfilePresenterFactory( AssistedInject_ProfilePresenter factory) }S
  83. @AssistedModule @Module(includes = [AssistedModule_PresenterModule::class]) object PresenterModule { @JvmStatic @Provides fun

    thing() = Thing("API key") }H @Module @Generated abstract class AssistedModule_PresenterModule { @Binds abstract ProfilePresenter.Factory bindProfilePresenterFactory( AssistedInject_ProfilePresenter factory) // … }S
  84. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B
  85. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B
  86. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B
  87. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B @Module abstract class MainActivityModule { }A
  88. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B @Module abstract class MainActivityModule { @ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity }A
  89. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B @Module abstract class MainActivityModule { @ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity }A @Component(modules = [MainActivityModule::class]) interface AppComponent
  90. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B @Module abstract class MainActivityModule { @ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity }A @Component(modules = [MainActivityModule::class]) interface AppComponent @Module abstract class MainActivityModule_ContributeMainActivity { … }
  91. class MainActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }C }B @Module abstract class MainActivityModule { @ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity }A @Component(modules = [MainActivityModule::class]) interface AppComponent @Module abstract class MainActivityModule_ContributeMainActivity { … }
  92. None
  93. None
  94. dependencies { compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.3.0' kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.3.0' }A

  95. dependencies { compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.3.0' kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.3.0' // or 'annotationProcessor'… }A

  96. class ProfileView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { }Z

  97. class ProfileView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { lateinit

    var imageLoader: ImageLoader lateinit var avatarRenderer: AvatarRenderer }Z
  98. class ProfileView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { lateinit

    var imageLoader: ImageLoader lateinit var avatarRenderer: AvatarRenderer fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z
  99. class ProfileView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { lateinit

    var imageLoader: ImageLoader lateinit var avatarRenderer: AvatarRenderer fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val avatarRenderer: AvatarRenderer, /*…*/ ) { }I
  100. class ProfileView(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) { lateinit

    var imageLoader: ImageLoader lateinit var avatarRenderer: AvatarRenderer fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val avatarRenderer: AvatarRenderer, /*…*/ ) { fun attachView(view: ProfileView) { }W }I
  101. l l class ProfileView(context: Context, attrs: AttributeSet)G : ConstraintLayout(context, attrs)

    { lateinit var imageLoader: ImageLoader lateinit var avatarRenderer: AvatarRenderer fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val avatarRenderer: AvatarRenderer, /*…*/ ) { fun attachView(view: ProfileView) { view.imageLoader = imageLoader view.avatarRenderer = avatarRenderer }W }I
  102. r r class ProfileView( context: Context, attrs: AttributeSet, val imageLoader:

    ImageLoader, val avatarRenderer: AvatarRenderer )G: ConstraintLayout(context, attrs) { fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val avatarRenderer: AvatarRenderer, /*…*/ ) { fun attachView(view: ProfileView) { view.imageLoader = imageLoader view.avatarRenderer = avatarRenderer }W }I
  103. class ProfileView( context: Context, attrs: AttributeSet, val imageLoader: ImageLoader, val

    avatarRenderer: AvatarRenderer )G: ConstraintLayout(context, attrs) { fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor( val imageLoader: ImageLoader, val avatarRenderer: AvatarRenderer, /*…*/ ) { fun attachView(view: ProfileView) { }W }I
  104. class ProfileView( context: Context, attrs: AttributeSet, val imageLoader: ImageLoader, val

    avatarRenderer: AvatarRenderer )G: ConstraintLayout(context, attrs) { fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor(/*…*/) { fun attachView(view: ProfileView) { }W }I
  105. class ProfileView( context: Context, attrs: AttributeSet, val imageLoader: ImageLoader, val

    avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { fun showProfile(profile: Profile) { // Use avatarRenderer… // Use imageLoader… }Y }Z class ProfilePresenter @AssistedInject constructor(/*…*/) { fun attachView(view: ProfileView) { }W }I
  106. class LayoutInflater { }A

  107. class LayoutInflater { interface Factory { }B }A

  108. class LayoutInflater { interface Factory { @Nullable View onCreateView( @NonNull

    String name, @NonNull Context context, @NonNull AttributeSet attrs); }B }A
  109. class LayoutInflater { interface Factory { @Nullable View onCreateView( @NonNull

    String name, @NonNull Context context, @NonNull AttributeSet attrs); }B }A class MyAppFactory : LayoutInflater.Factory { }P
  110. class LayoutInflater { interface Factory { @Nullable View onCreateView( @NonNull

    String name, @NonNull Context context, @NonNull AttributeSet attrs); }B }A class MyAppFactory : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { }O }P
  111. class LayoutInflater { interface Factory { @Nullable View onCreateView( @NonNull

    String name, @NonNull Context context, @NonNull AttributeSet attrs); }B }A class MyAppFactory : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return TODO() }I }O }P
  112. class LayoutInflater { interface Factory { @Nullable View onCreateView( @NonNull

    String name, @NonNull Context context, @NonNull AttributeSet attrs); }B }A class MyAppFactory : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return TODO() }I return null }O }P
  113. class ProfileView( context: Context, attrs: AttributeSet, private val imageLoader: ImageLoader,

    private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { }Z
  114. class ProfileView(G @Assisted context: Context, @Assisted attrs: AttributeSet, private val

    imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { }Z
  115. class ProfileView @AssistedInject constructor(G @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { }Z
  116. class ProfileView @AssistedInject constructor(G @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory { fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z
  117. class MyAppFactory : LayoutInflater.Factory { override fun onCreateView(name: String, context:

    Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return TODO() }I return null }O }P
  118. class MyAppFactory @Inject constructor() : LayoutInflater.Factory { override fun onCreateView(name:

    String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return TODO() }I return null }O }P
  119. class MyAppFactory @Inject constructor( private val profileViewFactory: ProfileView.Factory ) :

    LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return TODO() }I return null }O }P
  120. class MyAppFactory @Inject constructor( private val profileViewFactory: ProfileView.Factory ) :

    LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return profileViewFactory.create(context, attrs) }I return null }O }P
  121. class MyAppFactory @Inject constructor( private val profileViewFactory: ProfileView.Factory, private val

    cartViewFactory: CartView.Factory ) : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return profileViewFactory.create(context, attrs) }I if (name == CartView::class.java.name) { return cartViewFactory.create(context, attrs) }I return null }O }P
  122. class MyAppFactory @Inject constructor( private val profileViewFactory: ProfileView.Factory, private val

    cartViewFactory: CartView.Factory, private val checkoutViewFactory: CheckoutView.Factory ) : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return profileViewFactory.create(context, attrs) }I if (name == CartView::class.java.name) { return cartViewFactory.create(context, attrs) }I if (name == CheckoutView::class.java.name) { return checkoutViewFactory.create(context, attrs) }I return null }O }P
  123. class MyAppFactory @Inject constructor( private val viewFactories: Map<String, ViewFactory> )

    : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { if (name == ProfileView::class.java.name) { return profileViewFactory.create(context, attrs) }I if (name == CartView::class.java.name) { return cartViewFactory.create(context, attrs) }I if (name == CheckoutView::class.java.name) { return checkoutViewFactory.create(context, attrs) }I return null }O }P private val profileViewFactory: ProfileView.Factory, private val cartViewFactory: CartView.Factory, private val checkoutViewFactory: CheckoutView.Factory
  124. class MyAppFactory @Inject constructor( private val viewFactories: Map<String, ViewFactory> )

    : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { return viewFactories[name]?.create(context, attrs) }O }P if (name == ProfileView::class.java.name) { return profileViewFactory.create(context, attrs) }I if (name == CartView::class.java.name) { return cartViewFactory.create(context, attrs) }I if (name == CheckoutView::class.java.name) { return checkoutViewFactory.create(context, attrs) }I null
  125. class MyAppFactory @Inject constructor( private val viewFactories: Map<String, ViewFactory> )

    : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { return viewFactories[name]?.create(context, attrs) }O }P interface ViewFactory { fun create(context: Context, attrs: AttributeSet): View }
  126. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory {A fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z
  127. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory {A override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z
  128. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { }Q
  129. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { @Binds abstract fun profileView(factory: ProfileView.Factory): ViewFactory }Q
  130. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { @Binds @IntoMap abstract fun profileView(factory: ProfileView.Factory): ViewFactory }Q
  131. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract fun profileView(factory: ProfileView.Factory): ViewFactory }Q
  132. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract fun profileView(factory: ProfileView.Factory): ViewFactory }Q
  133. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { @AssistedInject.Factory interface Factory : ViewFactory { override fun create(context: Context, attrs: AttributeSet): ProfileView }G }Z @Module abstract class ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract fun profileView(factory: ProfileView.Factory): ViewFactory }Q
  134. class ProfileView @AssistedInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { // … }Z
  135. class ProfileView @InflationInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { // … }Z @Assisted
  136. class ProfileView @InflationInject constructor( @Assisted context: Context, @Assisted attrs: AttributeSet,

    private val imageLoader: ImageLoader, private val avatarRenderer: AvatarRenderer ) : ConstraintLayout(context, attrs) { // … }Z
  137. @Generated class InflationInject_ProfileView implements ViewFactory { private final Provider<ImageLoader> imageLoader;

    private final Provider<AvatarRenderer> avatarRenderer; @Inject InflationInject_ProfileView( Provider<ImageLoader> imageLoader, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.avatarRenderer = avatarRenderer; } @Override public View create(Context context, AttributeSet attrs) { return new ProfileView( context, attrs, imageLoader.get(), avatarRenderer.get()); } }
  138. @Generated class InflationInject_ProfileView implements ViewFactory { private final Provider<ImageLoader> imageLoader;

    private final Provider<AvatarRenderer> avatarRenderer; @Inject InflationInject_ProfileView( Provider<ImageLoader> imageLoader, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.avatarRenderer = avatarRenderer; } @Override public View create(Context context, AttributeSet attrs) { return new ProfileView( context, attrs, imageLoader.get(), avatarRenderer.get()); } }
  139. @Generated class InflationInject_ProfileView implements ViewFactory { private final Provider<ImageLoader> imageLoader;

    private final Provider<AvatarRenderer> avatarRenderer; @Inject InflationInject_ProfileView( Provider<ImageLoader> imageLoader, Provider<AvatarRenderer> avatarRenderer) { this.imageLoader = imageLoader; this.avatarRenderer = avatarRenderer; } @Override public View create(Context context, AttributeSet attrs) { return new ProfileView( context, attrs, imageLoader.get(), avatarRenderer.get()); } }
  140. @Module object ViewModule { }H

  141. @InflationModule @Module object ViewModule { }H

  142. @InflationModule @Module object ViewModule { }H @Module @Generated abstract class

    InflationModule_ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract ViewFactory bindProfileView( InflationInject_ProfileView factory) }S
  143. @InflationModule @Module(includes = [InflationModule_ViewModule::class]) object ViewModule { }H @Module @Generated

    abstract class InflationModule_ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract ViewFactory bindProfileView( InflationInject_ProfileView factory) }S
  144. @InflationModule @Module(includes = [InflationModule_ViewModule::class]) object ViewModule { }H @Module @Generated

    abstract class InflationModule_ViewModule { @Binds @IntoMap @StringKey("com.example.ProfileView") abstract ViewFactory bindProfileView( InflationInject_ProfileView factory) // … }S
  145. class MyAppFactory @Inject constructor( private val viewFactories: Map<String, ViewFactory> )

    : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { return viewFactories[name]?.create(context, attrs) }O }P
  146. class InflationInjectFactory @Inject constructor( private val viewFactories: Map<String, ViewFactory> )

    : LayoutInflater.Factory { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { return viewFactories[name]?.create(context, attrs) }O }P
  147. class ProfileActivity : Activity() { }A

  148. class ProfileActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) AndroidInjection.inject(this) }B }A
  149. class ProfileActivity : Activity() { @Inject lateinit var presenterFactory: ProfilePresenter.Factory

    @Inject lateinit var inflationFactory: InflationInjectFactory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) }B }A
  150. class ProfileActivity : Activity() { @Inject lateinit var presenterFactory: ProfilePresenter.Factory

    @Inject lateinit var inflationFactory: InflationInjectFactory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) layoutInflater.factory = inflationFactory }B }A
  151. class ProfileActivity : Activity() { @Inject lateinit var presenterFactory: ProfilePresenter.Factory

    @Inject lateinit var inflationFactory: InflationInjectFactory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) layoutInflater.factory = inflationFactory setContentView(R.layout.profile_view) }B }A
  152. class ProfileActivity : Activity() { @Inject lateinit var presenterFactory: ProfilePresenter.Factory

    @Inject lateinit var inflationFactory: InflationInjectFactory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) layoutInflater.factory = inflationFactory setContentView(R.layout.profile_view) val userId = intent.getStringExtra("userId") val presenter = presenterFactory.create(userId) presenter.attachView(findViewById(R.id.profile_view) }B }A
  153. class ProfileActivity : Activity() { @Inject lateinit var presenterFactory: ProfilePresenter.Factory

    @Inject lateinit var inflationFactory: InflationInjectFactory override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) layoutInflater.factory = inflationFactory setContentView(R.layout.profile_view) val userId = intent.getStringExtra("userId") val presenter = presenterFactory.create(userId) presenter.attachView(findViewById(R.id.profile_view) }B }A l l
  154. class ProfileActivity @Inject constructor( val presenterFactory: ProfilePresenter.Factory val inflationFactory: InflationInjectFactory

    : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AndroidInjection.inject(this) layoutInflater.factory = inflationFactory setContentView(R.layout.profile_view) val userId = intent.getStringExtra("userId") val presenter = presenterFactory.create(userId) presenter.attachView(findViewById(R.id.profile_view) }B }A @ I n j e c t l a t e i n i t r @ I n j e c t l a t e i n i t r
  155. None
  156. None
  157. None
  158. dependencies { compileOnly 'com.squareup.inject:inflation-inject:0.3.0' kapt 'com.squareup.inject:inflation-inject-processor:0.3.0' }A

  159. dependencies { compileOnly 'com.squareup.inject:inflation-inject:0.3.0' kapt 'com.squareup.inject:inflation-inject-processor:0.3.0' // or 'annotationProcessor'… }A

  160. None
  161. None
  162. None
  163. None
  164. None
  165. None
  166. allprojects { }A

  167. allprojects { tasks.withType(JavaCompile).all { }B }A

  168. allprojects { tasks.withType(JavaCompile).all { options.compilerArgs += []C }B }A

  169. allprojects { tasks.withType(JavaCompile).all { options.compilerArgs += [ '-Adagger.formatGeneratedSource=disabled' ]C }B

    }A
  170. allprojects { tasks.withType(JavaCompile).all { options.compilerArgs += [ '-Adagger.formatGeneratedSource=disabled' ]C }B

    afterEvaluate { extensions.findByName('kapt')?.arguments { arg("dagger.formatGeneratedSource", "disabled") }D }C }A
  171. None
  172. allprojects { tasks.withType(JavaCompile).all { options.compilerArgs += [ '-Adagger.formatGeneratedSource=disabled' ]C }B

    afterEvaluate { extensions.findByName('kapt')?.arguments { arg("dagger.formatGeneratedSource", "disabled") }D }C }A
  173. allprojects { tasks.withType(JavaCompile).all { options.compilerArgs += [ '-Adagger.formatGeneratedSource=disabled', '-Adagger.gradle.incremental=enabled' ]C

    }B afterEvaluate { extensions.findByName('kapt')?.arguments { arg("dagger.formatGeneratedSource", "disabled") arg("dagger.gradle.incremental", "enabled") }D }C }A
  174. None
  175. None
  176. None
  177. None
  178. None
  179. None
  180. None
  181. None
  182. None
  183. ButterKnife.bind(this)

  184. ButterKnife.bind(this) class ButterKnife { static Unbinder bind(Activity target) { //

    Class.forName lookup… } } butterknife-runtime.aar
  185. ButterKnife.bind(this) class ButterKnife { static Unbinder bind(Activity target) { //

    Reflection implementation… } } butterknife-reflect.aar class ButterKnife { static Unbinder bind(Activity target) { // Class.forName lookup… } } butterknife-runtime.aar
  186. dependencies { if (properties.containsKey('android.injected.invoked.from.ide')) { implementation 'com.jakewharton:butterknife-reflect:9.0.0-rc1' } else {

    implementation 'com.jakewharton:butterknife:9.0.0-rc1' kapt 'com.jakewharton:butterknife-compiler:9.0.0-rc1' }B }A
  187. dependencies { if (properties.containsKey('android.injected.invoked.from.ide')) { implementation 'com.jakewharton:butterknife-reflect:9.0.0-rc1' } else {

    implementation 'com.jakewharton:butterknife:9.0.0-rc1' kapt 'com.jakewharton:butterknife-compiler:9.0.0-rc1' // or 'annotationProcessor'… }B }A
  188. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A
  189. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerAppComponent.builder() .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  190. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerAppComponent.builder() .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  191. class DaggerReflect { }A

  192. class DaggerReflect { static <B> B builder(Class<B> builderClass) { }B

    }A
  193. class DaggerReflect {C static <B> B builder(Class<B> builderClass) { return

    (B) Proxy.newProxyInstance( builderClass.getClassLoader(), new Class[] { builderClass }, ComponentBuilderInvocationHandler.create(builderClass)); }B }A
  194. class DaggerReflect {C static <B> B builder(Class<B> builderClass) { return

    (B) Proxy.newProxyInstance( builderClass.getClassLoader(), new Class[] { builderClass }, ComponentBuilderInvocationHandler.create(builderClass)); }B }A
  195. class DaggerReflect {C static <B> B builder(Class<B> builderClass) { return

    (B) Proxy.newProxyInstance( builderClass.getClassLoader(), new Class[] { builderClass }, ComponentBuilderInvocationHandler.create(builderClass)); }B }A
  196. class DaggerReflect { static <C> C create(Class<C> componentClass) { return

    (C) Proxy.newProxyInstance( componentClass.getClassLoader(), new Class[] { componentClass }, ComponentInvocationHandler.create(componentClass)); }C static <B> B builder(Class<B> builderClass) { return (B) Proxy.newProxyInstance( builderClass.getClassLoader(), new Class[] { builderClass }, ComponentBuilderInvocationHandler.create(builderClass)); }B }A
  197. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerAppComponent.builder() .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  198. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerAppComponent.builder() .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  199. final class DaggerAppComponent { }A

  200. final class DaggerAppComponent { static AppComponent.Builder builder() { return DaggerReflect.builder(AppComponent.Builder.class);

    }B }A
  201. final class DaggerAppComponent { static AppComponent create() { return DaggerReflect.create(AppComponent.class);

    }C static AppComponent.Builder builder() { return DaggerReflect.builder(AppComponent.Builder.class); }B }A
  202. DaggerAppComponent.builder()

  203. DaggerAppComponent.builder() final class DaggerAppComponent { static AppComponent.Builder builder() { //

    real Dagger implementation… }B }A dagger-compiler.jar + dagger.jar
  204. DaggerAppComponent.builder() final class DaggerAppComponent { static AppComponent.Builder builder() { return

    DaggerReflect.builder( AppComponent.Builder.class); }B }A dagger-reflect.jar final class DaggerAppComponent { static AppComponent.Builder builder() { // real Dagger implementation… }B }A dagger-compiler.jar + dagger.jar
  205. dagger-compiler.jar dagger.jar dagger-reflect.jar

  206. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerAppComponent.builder() .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  207. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerReflect.builder(AppComponent.Builder::class) .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  208. class Dagger { }A

  209. class Dagger { static <B> B builder(Class<B> builderClass) { }B

    }A
  210. class Dagger { static <B> B builder(Class<B> builderClass) { return

    DaggerReflect.builder(builderClass); }B }A
  211. class Dagger { static <B> B builder(Class<B> builderClass) { return

    DaggerReflect.builder(builderClass); }B }A class Dagger { }A
  212. class Dagger { static <B> B builder(Class<B> builderClass) { return

    DaggerReflect.builder(builderClass); }B }A class Dagger { static <B> B builder(Class<B> builderClass) { }B }A
  213. class Dagger { static <B> B builder(Class<B> builderClass) { return

    DaggerReflect.builder(builderClass); }B }A class Dagger { static <B> B builder(Class<B> builderClass) { return builderClass.getMethod("builder").invoke(null); }B }A
  214. class Dagger { static <B> B builder(Class<B> builderClass) { return

    DaggerReflect.builder(builderClass); }B }A class Dagger { static <B> B builder(Class<B> builderClass) { return builderClass.getMethod("builder").invoke(null); }B }A dagger-reflect.jar dagger-codegen.jar
  215. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = DaggerReflect.builder(AppComponent.Builder::class) .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  216. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = Dagger.builder(AppComponent.Builder::class) .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  217. @Component(modules = [AppModule::class]) interface AppComponent { fun foo(): Foo fun

    bar(): Bar fun thermosiphon(): Thermosiphon @Component.Builder interface Builder { @BindsInstance fun apiKey(@ApiKey apiKey: String) fun build(): AppComponent }B }A val component = Dagger.builder(AppComponent.Builder::class) .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()
  218. val component = Dagger.builder(AppComponent.Builder::class)G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()

  219. val component = AppComponent.Builder::class.builder()G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build()

  220. val component = AppComponent.Builder::class.builder()G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build() // dagger-reflect: inline fun

    <B> KClass<B>.builder(): B = DaggerReflect.builder(java)
  221. val component = AppComponent.Builder::class.builder()G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build() // dagger-reflect: inline fun

    <B> KClass<B>.builder(): B = DaggerReflect.builder(java) // dagger-codegen: inline fun <B> KClass<B>.builder(): B = throw UnsupportedOperationException("…")
  222. val component = AppComponent.Builder::class.builder()G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build() // dagger-reflect: inline fun

    <B> KClass<B>.builder(): B = DaggerReflect.builder(java) // dagger-codegen: inline fun <B> KClass<B>.builder(): B = throw UnsupportedOperationException("…") // Generated from dagger-codegen-compiler: @JvmName("builderAppComponent") inline fun KClass<AppComponent.Builder>.builder() = AppComponent.builder()
  223. val component = AppComponent.Builder::class.builder()G .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build() // dagger-reflect: inline fun

    <B> KClass<B>.builder(): B = DaggerReflect.builder(java) // dagger-codegen: inline fun <B> KClass<B>.builder(): B = throw UnsupportedOperationException("…") // Generated from dagger-codegen-compiler: @JvmName("builderAppComponent") inline fun KClass<AppComponent.Builder>.builder() = AppComponent.builder()
  224. AppComponent.Builder::class.builder()G val component = .apiKey("IDt0n5RoTAc0l3CiVR3sRn13d0kdNaN1oK") .build() // dagger-reflect: inline fun

    <B> KClass<B>.builder(): B = DaggerReflect.builder(java) // dagger-codegen: inline fun <B> KClass<B>.builder(): B = throw UnsupportedOperationException("…") // Generated from dagger-codegen-compiler: @JvmName("builderAppComponent") inline fun KClass<AppComponent.Builder>.builder() = AppComponent.builder() AppComponent.builder()
  225. None
  226. None
  227. Helping Dagger Help You @JakeWharton