Search code examples
androiddependency-injectiondagger

Dagger: What if I *WANT* a new instance every time?


Interesting how difficult this answer is to find.

I've been using Dagger - Android for a while now and have my entire dependency graph set up. I'm using scopes, qualifiers, all that good stuff. I'm not a Dagger newbie anymore, but suffice to say I've been using it in a pretty standard way in my Android setup and everything has been going great.

For the first time, I'm realizing that I'd like to request new instances of a certain class in my graph myself, manually, and I want it to be a new instance every time.

What's the best way to go about doing that? I'm wondering if there's a way to leverage a non-@Singleton/non-scoped provider and call some sort of create() method myself, or if it's best to create a factory myself and make that factory a singleton/scoped instance and use my factory to get the new instance(s) when I need them? [I should mention this class will definitely not have an empty constructor so will need injected instances of other classes defined in my injection graph.]

(Also, it would probably help the most if answers were in the context of Android; i.e. I'm in, say, a ViewModel and need a new instance of some class defined in one of my Modules.)


Solution

  • Dagger will provide you a new instance as long as you don't scope the dependency.

    To get a new instance of a dependency manually, you can inject Provider of it instead and use its get() method, it'll give you a new instance every time you call it.

    Module part doesn't really change:

    @Module
    class AppModule {
    
        @Provides
        fun provideSomeObject(): SomeObject = SomeObject()
    }
    

    And in your class

    class SomeClass {
        // We don't inject the object anymore
        // @Inject lateinit var myObject : SomeObject
    
        // We'll inject it's provider
        @Inject lateinit var myObject : Provider<SomeObject>
    
        fun someMethod(){
            // Here, instance1 and instance2 are NOT same objects
            val instance1 = myObject.get()
            val instance2 = myObject.get()
        }
    }
    

    You can read more here.