Closed AndrewSB closed 8 months ago
Resetting a container (or scope) will only have an effect on future resolutions. Anything already resolved is already resolved.
let cached: Service? = Service()
let reference: Service? = cached
cached = nil
// what is reference?
that makes sense. so following my example above:
extension Container {
var currentLoggedInUserInfoProvider: Factory<CurrentLoggedInUserInfoProvider> {
self { CurrentLoggedInUserInfoProvider }.scope(.session)
}
}
class ApplicationCoordinator {
@Injected(\.currentLoggedInUserInfoProvider) var currentLoggedInUserInfoProvider
func logout() {
print(currentLoggedInUserInfoProvider) // instance #1
Container.shared.manager.reset(scope: .session)
let resolution = Container.shared.currentLoggedInUserInfoProvider.resolve() // new instance #2
print(currentLoggedInUserInfoProvider) // still instance #1?
}
}
i'd like applicationCoordinator.currentLoggedInUserInfoProvider
to resolve to the new instance #2, but it looks like it's still holding onto the instance that was resolved at ApplicationCoordinator.init()
time. is that correct?
assuming that is the case, i'd like it to point to a new instance, is that possible without adding something like self.currentLoggedInUserInfoProvider = Container.shared.currentLoggedInUserInfoProvider.resolve()
right after i run Container.shared.manager.reset(scope: .session)
?
Look at
$currentLoggedInUserInfoProvider.resolve(reset: .scope)
that looks like it allows me to force a clearing of the cache at resolution time. i think i failed to explain my example
print(currentLoggedInUserInfoProvider) // instance #1
Container.shared.manager.reset(scope: .session)
// i don't want to do a new resolution, not every object knows that the scope is being reset. it would be less-than-ideal if every object that's using an `@Injected` value needs to pay attention to the container being reset, and re-resolve then
let resolution = Container.shared.currentLoggedInUserInfoProvider.resolve() // new instance #2
// i'd like to, instead, be able to continue using `self.currentLoggedInUserInfoProvider`, and have something dynamic happen at reset time where the wrapped value from the property wrapper knows that it's old instance should be released
print(currentLoggedInUserInfoProvider) // still instance #1?
You're better off with something like....
class AuthenticatedUser {
var currentUser = CurrentValueSubject<User?, Never>(nil)
func logout() {
currentUser.send(nil)
}
}
That way everyone can see when a user is logged in, logged out, and get notified of changes when they occur.
It's not the job of the dependency injection system to track every existing resolution and attempt to re-resolve it.
Further some like InjectedObject are effectively immutable.
Hey! i'm trying to understand the best way to compose something like this. i have a long lived coordinator, that has injected references into objects that are reset. here's a simplified example
the issue that i have, is after logging out and resetting
.scope(.session)
, myApplicationCoordinator
still has a reference to that old instance.how should i solve this problem? is this a case where i can't use
@Injected
, and instead need to resolve imperatively whenever i want to usecurrentLoggedInUserInfoProvider
inApplicationCoordinator
?