Skip to content

Instantly share code, notes, and snippets.

@ts95
Created September 26, 2022 10:03
Show Gist options
  • Save ts95/d66da824bf9106ce0b1c8304482d2ec6 to your computer and use it in GitHub Desktop.
Save ts95/d66da824bf9106ce0b1c8304482d2ec6 to your computer and use it in GitHub Desktop.
Swift basic singleton-based dependency injection
import Foundation
@propertyWrapper
struct Injected<T> {
private let keyPath: WritableKeyPath<InjectedValues, T>
var wrappedValue: T {
get { InjectedValues[keyPath] }
set { InjectedValues[keyPath] = newValue }
}
init(_ keyPath: WritableKeyPath<InjectedValues, T>) {
self.keyPath = keyPath
}
}
import Foundation
/// Provides access to injected dependencies.
struct InjectedValues {
/// This is only used as an accessor to the computed properties within extensions of `InjectedValues`.
private static var current = InjectedValues()
/// A static subscript for updating the `currentValue` of `InjectionKey` instances.
static subscript<K>(key: K.Type) -> K.Value where K: InjectionKey {
get { key.currentValue }
set { key.currentValue = newValue }
}
/// A static subscript accessor for updating and references dependencies directly.
static subscript<T>(_ keyPath: WritableKeyPath<InjectedValues, T>) -> T {
get { current[keyPath: keyPath] }
set { current[keyPath: keyPath] = newValue }
}
}
import Foundation
// https://www.avanderlee.com/swift/dependency-injection/
public protocol InjectionKey {
/// The associated type representing the type of the dependency injection key's value.
associatedtype Value
/// The default value for the dependency injection key.
static var currentValue: Self.Value { get set }
}
@ts95
Copy link
Author

ts95 commented Sep 26, 2022

Example usage:

// MARK: - Dependency injection

private struct PersistenceControllerKey: InjectionKey {
    static var currentValue: PersistenceControllerProtocol = PersistenceController()
}

extension InjectedValues {
    var persistenceController: PersistenceControllerProtocol {
        get { Self[PersistenceControllerKey.self] }
        set { Self[PersistenceControllerKey.self] = newValue }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment