Skip to content

Instantly share code, notes, and snippets.

@adamdahan
Forked from werediver/ServiceLocator.swift
Created August 20, 2016 07:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamdahan/e4bb2a0610c7e0e1be522a959b027503 to your computer and use it in GitHub Desktop.
Save adamdahan/e4bb2a0610c7e0e1be522a959b027503 to your computer and use it in GitHub Desktop.
import Foundation
protocol ServiceLocator {
func getService<T>(type: T.Type) -> T?
func getService<T>() -> T?
}
extension ServiceLocator {
func getService<T>() -> T? {
return getService(T)
}
}
func typeName(some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(some.dynamicType)"
}
final class BasicServiceLocator: ServiceLocator {
// Service registry
private lazy var reg: Dictionary<String, Any> = [:]
func addService<T>(instance: T) {
let key = typeName(T)
reg[key] = instance
//print("Service added: \(key) / \(typeName(service))")
}
func getService<T>(type: T.Type) -> T? {
return reg[typeName(T)] as? T
}
}
final class LazyServiceLocator: ServiceLocator {
/// Registry record
enum RegistryRec {
case Instance(Any)
case Recipe(() -> Any)
}
/// Service registry
private lazy var reg: Dictionary<String, RegistryRec> = [:]
func addService<T>(recipe: () -> T) {
let key = typeName(T)
reg[key] = .Recipe(recipe)
}
func addService<T>(instance: T) {
let key = typeName(T)
reg[key] = .Instance(instance)
//print("Service added: \(key) / \(typeName(instance))")
}
func getService<T>(type: T.Type) -> T? {
var instance: T? = nil
if let registryRec = reg[typeName(T)] {
switch registryRec {
case .Instance(let _instance):
instance = _instance as? T
case .Recipe(let recipe):
instance = recipe() as? T
if let instance = instance {
addService(instance)
}
}
}
return instance
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment