Parent dependency is resolved from cache after child has changed, instead of being recalculated
kirillsh opened this issue · 1 comments
Description
In our project we're using dependencies that rely on other lower level dependencies. We're usually doing that by declaring @Dependency(\.child)
property wrapper inside parent's implementation of liveValue
.
But because parent's value is cached upon its first resolution -> no matter how we override the child's value, the parent will not be recalculated capturing its child's initial value.
This might produce unexpected side effects like in the example below.
Checklist
- I have determined whether this bug is also reproducible in a vanilla SwiftUI project.
- If possible, I've reproduced the issue using the
main
branch of this package. - This issue hasn't been addressed in an existing GitHub issue or discussion.
Expected behavior
Parent.liveValue
is recalculated after Child
is overwritten.
Actual behavior
Parent.liveValue
is resolved from cache capturing the initial Child
value.
Steps to reproduce
// -------- Declaring dependencies
struct Parent: DependencyKey {
let child: Child
static var liveValue: Parent {
@Dependency(Child.self)
var child
return Self(child: child)
}
}
struct Child: DependencyKey {
let id: String
static let liveValue = Child(id: "Child")
}
// --------- Consuming dependencies
withDependencies {
$0[Child.self] = Child(id: "Overriden Child")
} operation: {
@Dependency(Parent.self)
var parent
print(parent.child.id) // "Overriden Child"
}
@Dependency(Parent.self)
var parent
print(parent.child.id) // Expected: "Child", Actual: "Overriden Child"
Dependencies version information
1.3.0
Destination operating system
iOS 17
Xcode version information
15.4
Hi @kirillsh, the behavior you have demonstrated above is to be expected. By doing this:
static var liveValue: Parent {
@Dependency(Child.self) var child
return Self(child: child)
}
…you have decided to resolve the Child
dependency at this moment and pass a concrete version of the child to Parent
. There will not be another resolution of this dependency at a later time, and so nothing can change its value. The Child
object is held inside the Parent
outside of the dependency system.
I'm not entirely sure what you are trying to accomplish in your real code. Perhaps you can share something more real world. But since this isn't an issue with the library I am going to convert it to a discussion, and please feel free to continue the conversation over there.