Created
November 21, 2022 15:46
-
-
Save arashkashi/7ffadb7d300655c620bb09cba11260ed to your computer and use it in GitHub Desktop.
a light weight injection code.
This file contains 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
// MARK: Demontration of Usage of Injection system | |
// 1. First step: make the key object, the current value type is the one you are trying to add to injection system. | |
private struct BaseClassKey: InjectionKey { | |
static var currentValue: BaseClass = RealSubClass() | |
} | |
// 2. How to inject the currect value | |
func test() { | |
var dataController = TestDataStructure() | |
InjectedValues[\.networkProvider] = MockedSubClass() | |
dataController.networkProvider = RealSubClass() | |
dataController.performDataRequest() // prints: Data requested using the 'NetworkProvider' | |
} | |
// 3. How to use the currently injected value | |
struct TestDataStructure { | |
@Injected(\.networkProvider) var networkProvider: BaseClass | |
func performDataRequest() { | |
networkProvider.requestData() | |
} | |
} | |
class BaseClass { | |
func requestData() { | |
} | |
} | |
class RealSubClass: BaseClass { | |
override func requestData() { | |
print("Data requested using the `NetworkProvider`") | |
} | |
} | |
class MockedSubClass: BaseClass { | |
override func requestData() { | |
print("Data requested using the `MockedNetworkProvider`") | |
} | |
} | |
// MARK: Implementation of Injection System | |
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 } | |
} | |
extension InjectedValues { | |
var networkProvider: BaseClass { | |
get { Self[BaseClassKey.self] } | |
set { Self[BaseClassKey.self] = newValue } | |
} | |
} | |
/// 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 } | |
} | |
} | |
@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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
source --> https://www.avanderlee.com/swift/dependency-injection/