I have been Dagger with the pre Android Injector style for a while, and have now decided to try the new methods. Til now, I was basically declaring on AppComponent like this:
@Singleton
@Component(
modules = [ApplicationModule::class,
NetModule::class,
ApiModule::class,
AnalyticsModule::class,
DbModule::class,
RepositoryModule::class,
InteractorModule::class]
)
interface ApplicationComponent {
fun inject(app: MyApp)
fun plus(controllerModule: ControllerModule): ControllerComponent
}
Then I would inject my Activities/Fragments/Services/Dialogs like this:
class MyActivity : AppCompatActivity() {
...
val component by lazy {
(application as MyApp)
.applicationComponent
.plus(
ControllerModule(this)
)
}
override fun inject() {
component.inject(this)
}
...
}
Basically I had one top level app component with app-traversal modules, then an activity level component (ControllerComponent) with per-activity instances, common to all activities.
Now that I switched to the new methods, I create my component like so:
@Singleton
@Component(
modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
NetModule::class,
ApiModule::class,
AnalyticsModule::class,
DbModule::class,
RepositoryModule::class,
InteractorModule::class
]
)
interface AppComponent : AndroidInjector<SoulpicksApp> {
@Component.Builder
interface Builder {
fun build(): AppComponent
@BindsInstance
fun application(application: SoulpicksApp): Builder
}
}
Make my app extend DaggerApplication:
open class MyApp : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<out DaggerApplication> = DaggerAppComponent.builder().application(this).build()
}
And my Activities/Fragments extend DaggerAppCompatActivty/DaggerFragment respectively:
class MyActivity : DaggerAppCompatActivity() {
...
}
I understand this should automatically wire up all the activities dependencies, provided Dagger is properly set up. However I havent declared my ControllerModule/Component so of course when running my app I get:
e: /Users/user/dev/my-android/app/build/generated/source/kapt/devDebug/com/myapp/android/di/activity/ActivityBinder_ContributesMyActivity.java:28: error: @Subcomponent.Builder is missing setters for required modules or subcomponents: [com.myapp.android.di.controller.ControllerModule]
I understand previously I was creating this component on each Activity by using the plus() method and injecting explicitly (which is what I am trying to avoid here), how can I do that now?
Also, I have some BottomSheetDialogFragments and JobServiceIntents in my app, and theres no equivalent DaggerBottomSheedDialogFragments/DaggerJobServiceIntents to extend from, how can I work around that?
ControllerModule:
@Module
class ControllerModule(val activity: androidx.fragment.app.FragmentActivity) {
@Provides
@ControllerScope
fun context(): Context = activity
@Provides
@ControllerScope
fun activity() = activity
@Provides
@ControllerScope
fun layoutInflater() = activity.layoutInflater
@Provides
@ControllerScope
fun fragmentManager(): androidx.fragment.app.FragmentManager = activity.supportFragmentManager
@Provides
@ControllerScope
fun provideNavigationController(activity: androidx.fragment.app.FragmentActivity, analyticsManager: AnalyticsCompositeManager) = NavigationController(activity, analyticsManager)
@Provides
@ControllerScope
fun providePackageUtils(activity: androidx.fragment.app.FragmentActivity) : PackageUtils = PackageUtilsImpl(activity)
}
from Submodules with Dagger and AndroidInjectors
No comments:
Post a Comment