Created
December 3, 2019 15:25
-
-
Save vialyx/83c05c57ffc6318c2fb1df04481ff99d 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
protocol ServiceLocator { | |
func getService<T>(_: T.Type) -> T | |
func getService<T>() -> T | |
} | |
extension ServiceLocator { | |
func getService<T>() -> T { | |
return getService(T.self) | |
} | |
} | |
final class LazyServiceLocator: ServiceLocator { | |
enum RegistryRecord { | |
case instance(Any) | |
case recipe(() -> Any) | |
} | |
fileprivate lazy var registry: [String: RegistryRecord] = [:] | |
func addService<T>(_ recipe: @escaping () -> T) { | |
let key = typeName(T.self) | |
registry[key] = .recipe(recipe) | |
} | |
func addService<T>(_ instance: T) { | |
let key = typeName(T.self) | |
registry[key] = .instance(instance) | |
} | |
func getService<T>(_: T.Type) -> T { | |
let instanceToFind: T? | |
if let registryRec = registry[typeName(T.self)] { | |
switch registryRec { | |
case .instance(let _instance): | |
instanceToFind = _instance as? T | |
case .recipe(let recipe): | |
instanceToFind = recipe() as? T | |
if let instance = instanceToFind { | |
addService(instance) | |
} | |
} | |
} else { | |
instanceToFind = nil | |
} | |
return instanceToFind! | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment