Skip to content

Instantly share code, notes, and snippets.

@cjnevin
Last active November 3, 2022 05:05
Show Gist options
  • Select an option

  • Save cjnevin/41b773c869a326721597ce881899f66e to your computer and use it in GitHub Desktop.

Select an option

Save cjnevin/41b773c869a326721597ce881899f66e to your computer and use it in GitHub Desktop.
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