1

I have a feature where I need to have different Room Databases for different users. I am using Dagger 2 for creating Room Database. My Application Component creates one room database. When user switches to another user I want to create new Room Database for that I would need new Application component to be created. I am able to do that but the old one will still exist. How can I destroy the old Application Component and Create new Application Component.

I am defining Application Component in Application class as shown below:

var daggerComponent: ApplicationComponent? = null
 daggerComponent = DaggerApplicationComponent.builder().application(this).build()
 ApplicationInjector.init(this) { application ->
 daggerComponent?.inject(application)
}

When switching users I am trying to do this:

val appComponent = DaggerApplicationComponent.builder().application(application = application).build()
ApplicationInjector.init(propertyManagerApplication) { application ->
appComponent?.inject(application)
}

How can I destroy the old component completely and then create a new component so that only one component exists at a point of time

keshav kowshik
  • 2,354
  • 4
  • 22
  • 45

1 Answers1

2

I think you're approaching this from the wrong angle.

You should have your Room database in a component with a different scope than the ApplicationComponent has. Then you could be rebuilding this component easily, anytime and all dependencies that relate strictly to User session would be separated.


E.g. (writing off the top of my head, so not tested)

  1. Create a custom Scope
@Scope
@Retention(value = AnnotationRetention.RUNTIME)
annotation class UserSessionScope
  1. Create a Subcomponent (use the created Scope):
@UserSessionScope
@Subcomponent
interface UserSessionComponent {

    @Subcomponent.Factory
    interface Factory {
        fun create(): UserSessionComponent
    }

    // INITIALIZE YOUR ROOM DATABASE
    // AND ALL DEPENDENCIES THAT DEPEND ON THE ROOM DATABASE

    // inject functions, etc.
}
  1. A new module to notify Dagger of subcomponents:
@Module(subcomponents = UserSessionComponent::class)
class SubcomponentsModule {}
  1. In your ApplicationComponent:
@Singleton
@Component(modules = [SubcomponentsModule::class])
interface ApplicationComponent {
    
    fun userSessionComponent(): UserSessionComponent.Factory
 
}
  1. Maintain the UserSessionComponent in your Application as long as the user session is maintained (user is not switched).
class YourApplication : Application() {

    lateinit var appComponent : ApplicationComponent
    lateinit var userSessionComponent : UserSessionComponent

    override fun onCreate() {
        //...
        initAppComponent();
        createUserSession();
    }

    private fun initAppComponent() {
         appComponent = DaggerApplicationComponent.builder().application(this).build()
    }

    fun createUserSession() {
        userSessionComponent = appComponent.userSessionComponent().create()
    }
}

Now all your Application scoped dependencies will be held within ApplicationComponent and maintained as long as the Application is alive. UserSessionComponent will maintain all dependencies that have a shorter lifespan (exist as long as the User session is valid).

Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
  • Thanks a lot. Will try this. – keshav kowshik Aug 12 '20 at 12:51
  • I tried this approach but my other modules are linked to RoomModule so I will have to move all modules to sub component will that cause any issues? – keshav kowshik Aug 13 '20 at 09:09
  • If they are linked to your room module then they depend on the user session. This is a valid observation from the dagger itself. When your database changes, related dependencies should be rebuilt as well. – Bartek Lipinski Aug 13 '20 at 09:20