Skip to content

Instantly share code, notes, and snippets.

@FGoessler
Created January 24, 2016 20:45
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save FGoessler/2b7df61ab3fb81048de3 to your computer and use it in GitHub Desktop.
Save FGoessler/2b7df61ab3fb81048de3 to your computer and use it in GitHub Desktop.
A very lightweight ServiceLocator implementation including a module mechanism written in Swift.
import Foundation
public protocol ServiceLocatorModul {
func registerServices(serviceLocator: ServiceLocator)
}
public class ServiceLocator {
private var registry = [ObjectIdentifier:Any]()
public static var sharedLocator = ServiceLocator()
init() {
registerModules([CocoaDefaultModul()])
}
// MARK: Registration
public func register<Service>(factory: () -> Service) {
let serviceId = ObjectIdentifier(Service.self)
registry[serviceId] = factory
}
public static func register<Service>(factory: () -> Service) {
sharedLocator.register(factory)
}
public func registerSingleton<Service>(singletonInstance: Service) {
let serviceId = ObjectIdentifier(Service.self)
registry[serviceId] = singletonInstance
}
public static func registerSingleton<Service>(singletonInstance: Service) {
sharedLocator.registerSingleton(singletonInstance)
}
public func registerModules(modules: [ServiceLocatorModul]) {
modules.forEach { $0.registerServices(self) }
}
public static func registerModules(modules: [ServiceLocatorModul]) {
sharedLocator.registerModules(modules)
}
// MARK: Injection
public static func inject<Service>() -> Service {
return sharedLocator.inject()
}
// This method is private because no service which wants to request other services should
// bind itself to specific instance of a service locator.
private func inject<Service>() -> Service {
let serviceId = ObjectIdentifier(Service.self)
if let factory = registry[serviceId] as? () -> Service {
return factory()
} else if let singletonInstance = registry[serviceId] as? Service {
return singletonInstance
} else {
fatalError("No registered entry for \(Service.self)")
}
}
}
class CocoaDefaultModul: ServiceLocatorModul {
func registerServices(serviceLocator: ServiceLocator) {
serviceLocator.register { NSNotificationCenter.defaultCenter() }
serviceLocator.register { NSUserDefaults.standardUserDefaults() }
serviceLocator.register { NSURLSession.sharedSession() }
serviceLocator.register { UIScreen.mainScreen() }
serviceLocator.register { UIApplication.sharedApplication() }
serviceLocator.register { UIApplication.sharedApplication().delegate! }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment