Last active
November 3, 2022 05:05
-
-
Save cjnevin/41b773c869a326721597ce881899f66e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public protocol DependencyKey { | |
| associatedtype Value | |
| static var currentValue: Self.Value { get set } | |
| } | |
| public protocol LazyDependencyKey { | |
| associatedtype Value | |
| static var currentValue: Self.Value? { get set } | |
| } | |
| extension LazyDependencyKey { | |
| static var value: Self.Value { | |
| get { | |
| guard let currentValue = currentValue else { | |
| preconditionFailure("A value must be set before trying to access this property.") | |
| } | |
| return currentValue | |
| } | |
| set { | |
| currentValue = newValue | |
| } | |
| } | |
| } | |
| public class DependencyContainer { | |
| private static var current = DependencyContainer() | |
| public static subscript<K>(key: K.Type) -> K.Value where K: DependencyKey { | |
| get { key.currentValue } | |
| set { key.currentValue = newValue } | |
| } | |
| public static subscript<K>(key: K.Type) -> K.Value where K: LazyDependencyKey { | |
| get { key.value } | |
| set { key.value = newValue } | |
| } | |
| public static subscript<T>(_ keyPath: WritableKeyPath<DependencyContainer, T>) -> T { | |
| get { current[keyPath: keyPath] } | |
| set { current[keyPath: keyPath] = newValue } | |
| } | |
| public static func set<K>(initialValue: K.Value, key: K.Type) where K: DependencyKey { | |
| key.currentValue = initialValue | |
| } | |
| public static func set<K>(initialValue: K.Value, key: K.Type) where K: LazyDependencyKey { | |
| key.value = initialValue | |
| } | |
| } | |
| @propertyWrapper | |
| public struct Dependency<T> { | |
| private let keyPath: WritableKeyPath<DependencyContainer, T> | |
| public var wrappedValue: T { | |
| get { DependencyContainer[keyPath] } | |
| set { DependencyContainer[keyPath] = newValue } | |
| } | |
| public init(_ keyPath: WritableKeyPath<DependencyContainer, T>) { | |
| self.keyPath = keyPath | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment