CODESAMPLE
Service Locator - Swift
The Service Locator pattern provides a centralized way to access services within an application. Instead of a component directly creating or locating its dependencies, it asks a “locator” for them. This promotes loose coupling, makes testing easier by allowing dependency injection through the locator, and simplifies management of complex dependencies. The Swift implementation uses a static shared instance to act as the central registry. Services are registered using a dictionary keyed by a designated type. The code demonstrates registration of a Logger service and its subsequent retrieval in a ViewController. This approach aligns well with Swift’s reliance on dependency injection and ease of use of dictionaries.
// ServiceLocator.swift
protocol Service { }
final class ServiceLocator {
static let shared = ServiceLocator()
private init() {}
private var services: [Type: Any] = [:]
func register<T: Service>(service: T) {
services[T.self] = service
}
func resolve<T: Service>() -> T? {
return services[T.self] as? T
}
}
// LoggerService.swift
protocol Logger: Service {
func log(message: String)
}
class DefaultLogger: Logger {
func log(message: String) {
print("LOG: \(message)")
}
}
// ViewController.swift
class MyViewController: UIViewController {
let logger: Logger? = ServiceLocator.shared.resolve()
override func viewDidLoad() {
super.viewDidLoad()
logger?.log(message: "View controller loaded.")
}
}
// Usage (e.g., in your app delegate or main setup)
func setupServices() {
ServiceLocator.shared.register(service: DefaultLogger())
}
setupServices()
// Example of using the view controller:
let viewController = MyViewController()
viewController.view.backgroundColor = .white
viewController.title = "Service Locator Demo"