hmlongco / Resolver

Swift Ultralight Dependency Injection / Service Locator framework
MIT License
2.15k stars 190 forks source link

How to replace already injected instances? (Access token issues) #102

Closed eralnar closed 3 years ago

eralnar commented 3 years ago

Hey! Here a come with a question.

How should I replace already injected instances when I reset the .cached scope?

My services:

register { SecretsManager() }
            .scope(.application)
register { PrivateApiManager() }
            .scope(.cached)

I use @Injected to inject the SecretsManager instance into PrivateApiManager so in its initializer I can use the SecretsManager.token property to instantiate PrivateApiManager.requestDispatcher.

When user performs a login action and gets the access token then I need to ResolverScope.cached.reset() so a new PrivateApiManager() is registered. The problem comes to the already @Injected PrivateApiManager instance in my ViewModels, is there a way to replace the old instance with the new one?

I was thinking of changing requestDispatcher to be a computed property so I can instantiate a new object every time I make a request, but I think that would be a performance issue. I thought of using .cached scope then, but I didn't find a way to get a reference to my new PrivateApiManager instance on my already instantiated ViewModels.

Thank you so much for developing Resolver, Diego.

hmlongco commented 3 years ago

So.... if you did the following...

class ViewModel {
   var service = MyService()
   ...
}

Would you expect service to magically update itself to a new instance sometime later on once you've made a ViewModel?

If you had...

class ViewModel {
   var service: MyService
   init(_ service: MyService) {
    self.service = service
   }
   ...
}

Would service automatically update itself to a new service once its' been passed to the initializer and assigned?

So...

class ViewModel {
   @Injected var service: MyService
   ...
}

Why would this behave differently?

@injected provides instances of objects when the class or struct is initialized. Once it's done so that object exists for the lifecycle of the parent object.

Long story short. This is an architecture issue. If you want an object to have new instances your best bet is to dump the old object and create a new object when a new user logs into your app.