Skip to content

Instantly share code, notes, and snippets.

@vialyx
Created December 3, 2019 15:25
Show Gist options
  • Save vialyx/83c05c57ffc6318c2fb1df04481ff99d to your computer and use it in GitHub Desktop.
Save vialyx/83c05c57ffc6318c2fb1df04481ff99d to your computer and use it in GitHub Desktop.
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