Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Inject Moshi/Gson in Room TypeConvertors using Hilt?

I am trying out hilt and i want to inject moshi for serializing and deserializing.

Here's a code sample from a github Repo which is not using di:

open class InfoTypeConverter {

private val moshi = Moshi.Builder().build() //not using dependency injection

  @TypeConverter
  fun fromString(value: String): PokemonInfo.Type? {
    val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
    return adapter.fromJson(value)
  }

  @TypeConverter
  fun fromInfoType(type: PokemonInfo.Type): String {
    val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
    return adapter.toJson(type)
  }
}

I am Trying out random stuff to field inject this like annotaion with @AndroidEntryPoint/@EntryPoint and obviously it's not working.

like image 399
Isac Avatar asked Aug 14 '20 11:08

Isac


1 Answers

Including Moshi in the Hilt dependency graph is as simple as adding this class:

@Module
@InstallIn(ApplicationComponent::class)
object DataModule {

  @Singleton
  @Provides
  fun provideMoshi(): Moshi {
      return Moshi.Builder().build()
  }
}

@TypeConverters are for the Room database. If you want to use the Moshi from Hilt for them, you will have to try a bit. One way of doing this is:

  1. Put @TypeConverter functions in a static context (object declaration) with an initializer
object InfoTypeConverter {

    private lateinit var moshi: Moshi

    fun initialize(moshi: Moshi){
        this.moshi = moshi
    }

    
    @TypeConverter
    fun fromString(value: String): PokemonInfo.Type? {
      val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
      return adapter.fromJson(value)
    }

    @TypeConverter
    fun fromInfoType(type: PokemonInfo.Type): String {
      val adapter: JsonAdapter<PokemonInfo.Type> = moshi.adapter(PokemonInfo.Type::class.java)
      return adapter.toJson(type)
    }
}
  1. Initialize InfoTypeConverter before creating your RoomDatabase (here using the same module for the purpose):
@Module
@InstallIn(ApplicationComponent::class)
object DataModule {

  @Singleton
  @Provides
  fun provideMoshi(): Moshi {
      return Moshi.Builder().build()
  }

  @Singleton
  @Provides
  fun provideRoomDatabase(moshi: Moshi): YourDatabase {
      InfoTypeConverter.initialize(moshi)
      val yourDatabase: YourDatabase = /* create your room database here */
      return yourDatabase
  }
}
like image 140
Bartek Lipinski Avatar answered Sep 22 '22 14:09

Bartek Lipinski