Reputation: 6009
I am developing an Android project with Kotlin and Dagger 2. I have a MyModule
in which I defined some provider functions.
@Module
object MyModule {
@Provides
@JvmStatic
internal fun provideSomething(): Something {
...
}
}
In my Foo
class, I inject Something
as a member variable:
class Foo(@Inject val something: Something) {
}
But now I want to have this Foo
class also be injectable to another class, e.g. in a class called Bar
:
class Bar(@Inject val foo: Foo)
How to make that happen? If in Java I could do:
class Foo {
// I inject something
@Inject
private Something something;
// I also make Foo to be injectable to other class
@Inject
public Foo()
}
But how to achieve the same in my Kotlin Foo
class?
Upvotes: 0
Views: 1862
Reputation: 3190
Assuming Something
is a class created by you. You don't even need a @Module
to provide it.
You can do this,
class Something @Inject constructor() {
}
You just add @Inject to Something
constructor and that's it, Dagger knows how to provide it. And then in your Foo
class
class Foo @Inject constructor() {
@Inject
lateinit var something: Something
}
Done, no need to have @Module and @Component if you own Something
class.
But
If the class Something
is not under your control then we need to take the long route such as,
Step 1: Create Module
@Module
object MyModule {
@Provides
@JvmStatic
internal fun provideSomething(): Something {
...
}
}
Step 2: Define Component
@Component(modules = [MyModule::class])
interface MyComponent {
fun inject(foo: Foo) //mention the place where you need to inject variables
}
Step 3: Start Component
class Foo @Inject constructor(){
@Inject
lateinit var something:Something
init{
DaggerMyComponent().create().inject(this) //do this before using `something` or else face `UninitializedPropertyException`
//You can now freely use `something`, **Dagger** has already performed his magic
}
}
Update:
Let's say Something
has a parameterized constructor and looks like this,
class Something @Inject constructor(mRandom : RandomClass)
, again two possibilities arise
If RandomClass
is owned by you, you can just add @Inject to this RandomClass
constructor like this,
class RandomClass @Inject constructor(){
}
that's it, Dagger will provide RandomClass
wherever needed.
And If RandomClass
is not under your control you need to provide it using a @Module
like this,
@Module
object RandomModule {
@JvmStatic
@Provides
fun providesRandomClass(): RandomClass {
...
}
}
Add this @Module
to your @Component
and start the @Component
wherever dependencies are needed(Example is already provided above in steps).
Moral of the story is, One way or another Dagger should know how to provide RandomClass
For your specific example, let's say we have
class Something @Inject constructor(mString:String,customType:CustomType){
}
Just tell Dagger how to provide that String
and CustomType
@Module
object CustomModule {
@JvmStatic
@Provides
@Named("AnyName") //Just to differentiate which string we need
fun providesString() = "AnyName"
@JvmStatic
@Provides
fun providesCustomType(): CustomType {
...
}
}
and then this last little modification over Something
constructor,
class Something @Inject constructor( @Named("AnyName") mString:String, customType:CustomType ){
}
Upvotes: 2
Reputation: 8371
In kotlin you have to do it like this:
class Foo @Inject constructor(val something: Something) {
}
I'm not so sure if you can name them the same either.
Upvotes: 0