Reputation: 313
Recently I started to divide our application into smaller Android modules, but I can't figure out how to structure dagger so it works for me.
My approach is to divide "bigger" features into smaller modules. Most of my features is within a base
module for now.
What I have working right now:
App
^
|
Base
^
|
Mvvm core
MyDagger setup consists of:
- a @Singleton
scoped AppComponent
- a @UserScope
subcomponent UserComponent
Both of which is placed in the Base
module.
What I'm trying to achieve:
App
^
|
Feature 1 - Feature 2
^
|
Base
^
|
Mvvm core
My plan is that each feature will have a @FeatureX
subcomponent within their own module - but this is where everything falls apart.
I can't figure out how to expose the SubComponent.Build
to each of my feature modules.
Is this even the right approach or what am I missing?
Bonus info: I have also tried to move the AppComponent
& UserComponent
into the App
module, but then I lack access to the component, which I need for injection, from my feature module(s).
Upvotes: 0
Views: 277
Reputation: 7368
Let's say you've created an android module named cookie which contains an activity and a dagger module.
CookieActivity:
class CookieActivity : DaggerAppCompatActivity() {
@Inject
lateinit var name: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cookie)
findViewById<TextView>(R.id.name).text = name
}
}
CookieModule:
@Module
abstract class CookieModule {
@ContributesAndroidInjector
abstract fun cookieActivity(): CookieActivity
@Module
companion object {
@Provides
@JvmStatic
fun provideName() = "Oreo"
}
}
Now you want to use this CookieActivity
from your main application. First you need to create your AppComponent
(note that the CookieModule
is installed inside the component):
@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, CookieModule::class])
interface AppComponent : AndroidInjector<App>
Then make your Application
class able to inject activity and fragment:
class App : Application(), HasActivityInjector, HasSupportFragmentInjector {
@Inject
internal lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
@Inject
internal lateinit var dispatchingFragmentInjector: DispatchingAndroidInjector<Fragment>
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder()
.build()
.inject(this)
}
override fun activityInjector(): AndroidInjector<Activity>? {
return dispatchingActivityInjector
}
override fun supportFragmentInjector(): AndroidInjector<Fragment>? {
return dispatchingFragmentInjector
}
}
You can now use your CookieActivity
and the main application will take care of the injection:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.button).setOnClickListener {
val intent = Intent(this, CookieActivity::class.java)
startActivity(intent)
}
}
}
"Oreo" will be shown as provided by the CookieModule
.
Upvotes: 1