user842225
user842225

Reputation: 6009

Dagger 2: Make a class injectable in other classes Kotlin

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

Answers (2)

iCantC
iCantC

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

apksherlock
apksherlock

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

Related Questions