AutoCat/AutoCatCore/DependencyInjection/ServiceContainer.swift

65 lines
1.8 KiB
Swift

//
// ServiceContainer.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 21.09.2024.
// Copyright © 2024 Selim Mustafaev. All rights reserved.
//
public enum DIError: Error {
case wrongServiceType(String)
case serviceNotFound(String)
var localizedDescription: String {
switch self {
case .wrongServiceType(let type): "Wrong service type for service: \(type)"
case .serviceNotFound(let type): "Service \(type) not found"
}
}
}
@MainActor
public class ServiceContainer {
public static let shared: ServiceContainer = .init()
private var cache: [String: Any] = [:]
private var factories: [String: () -> Any] = [:]
public func register<Service>(_ service: Service.Type,
factory: @autoclosure @escaping () -> Service) {
factories[String(describing: service.self)] = factory
}
public func register<Service>(_ service: Service.Type,
instance: Service) {
cache[String(describing: service.self)] = instance
}
public func resolve<Service>(_ service: Service.Type) throws -> Service {
let type = String(describing: service.self)
if let cachedService = cache[type] {
if let service = cachedService as? Service {
return service
} else {
throw DIError.wrongServiceType(type)
}
}
guard let factory = factories[type] else {
throw DIError.serviceNotFound(type)
}
if let service = factory() as? Service {
return service
} else {
throw DIError.wrongServiceType(type)
}
}
}