androiddagger-2dagger-hilt

Hilt - Question on making a Dao object in a module a Singleton


I'm following the tutorial on dependency injection with Hilt using the Google Sunflower app repo:

@InstallIn(SingletonComponent::class)
@Module
class DatabaseModule {

    @Singleton
    @Provides
    fun provideAppDatabase(@ApplicationContext context: Context): AppDatabase {
        return AppDatabase.getInstance(context)
    }

    @Provides
    fun providePlantDao(appDatabase: AppDatabase): PlantDao {
        return appDatabase.plantDao()
    }

    @Provides
    fun provideGardenPlantingDao(appDatabase: AppDatabase): GardenPlantingDao {
        return appDatabase.gardenPlantingDao()
    }
}

https://github.com/android/sunflower/blob/main/app/src/main/java/com/google/samples/apps/sunflower/di/DatabaseModule.kt

I noticed they did not use the Singleton annotation for the two functions below provideAppDatabase().

Does this mean that by using the Singleton annotation on provideAppDatabase, automatically make the two functions providePlantDao() and provideGardenPlantingDao() Singletons?


Other tutorials I've checked, annotate the Dao provide functions with @Singleton.

@Module
@InstallIn(SingletonComponent::class)
object DbModule {
    @Provides
    @Singleton
    fun provide(@ApplicationContext context: Context) = Room.databaseBuilder(
        context, NoteDatabase::class.java, NOTE_DATABASE)
        .allowMainThreadQueries()
        .fallbackToDestructiveMigration()
        .build()

    @Provides
    @Singleton
    fun provideDao(db: NoteDatabase) = db.noteDoa()
  
}

https://androidgeek.co/how-to-use-hilt-with-room-database-complete-guide-part-2-2c2bbf52f610

So I'm confused on to annotate or not to.


Solution

  • In the DatabaseModule class in the Sunflower app, the provideAppDatabase() function is annotated with the @Singleton annotation, which means that it will be a singleton object within the scope of the SingletonComponent class. This means that only one instance of the AppDatabase class will be created and provided when the provideAppDatabase() function is called, and this instance will be shared among all the components that depend on it.

    The providePlantDao() and provideGardenPlantingDao() functions, on the other hand, are not annotated with the @Singleton annotation. This means that these functions will be called each time they are injected, and a new instance of the PlantDao or GardenPlantingDao class will be created and provided each time.

    In general, it is a good practice to annotate any objects that you want to be singletons with the @Singleton annotation. This helps to ensure that only one instance of the object is created and shared among all the components that depend on it, which can improve the efficiency and performance of your app.

    In the second example you provided, the DbModule object is annotated with the @Singleton annotation, and both the provide() and provideDao() functions are also annotated with the @Singleton annotation. This means that both the NoteDatabase and NoteDao objects will be singletons within the scope of the SingletonComponent class.

    I hope this helps to clarify the use of the @Singleton annotation in dependency injection with Hilt.