|
| 1 | +// |
| 2 | +// Container.swift |
| 3 | +// Astroject |
| 4 | +// |
| 5 | +// Created by Porter McGary on 2/25/25. |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | + |
| 10 | +// ✅ Registration |
| 11 | +// ✅ Resolution |
| 12 | +// TODO: InstanceStore |
| 13 | + |
| 14 | +public class Container { |
| 15 | + var factories: ThreadSafeDictionary<FactoryKey, any FactoryRegistrable> = .init() |
| 16 | + |
| 17 | + public init() {} |
| 18 | + |
| 19 | + public func registerAsync<Product>(_ productType: Product.Type, name: String? = nil, factory block: @escaping (Resolver) async -> Product) { |
| 20 | + let factoryKey = FactoryKey(productType: productType, name: name) |
| 21 | + let factory = Factory.async(block) |
| 22 | + let registration = FactoryRegistration(factory: factory) |
| 23 | + factories.insert(registration, for: factoryKey) |
| 24 | + } |
| 25 | + |
| 26 | + public func register<Product>(_ productType: Product.Type, name: String? = nil, factory block: @escaping (Resolver) -> Product) { |
| 27 | + let factoryKey = FactoryKey(productType: productType, name: name) |
| 28 | + let factory = Factory.sync(block) |
| 29 | + let registration = FactoryRegistration(factory: factory) |
| 30 | + factories.insert(registration, for: factoryKey) |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +extension Container: Resolver { |
| 35 | + public func resolve<Product>(_ productType: Product.Type, name: String?) -> Product? { |
| 36 | + let registration = registration(for: productType, with: name) |
| 37 | + let product = registration?.factory.make(self) |
| 38 | + return product |
| 39 | + } |
| 40 | + |
| 41 | + public func resolveAsync<Product>(_ productType: Product.Type, name: String?) async -> Product? { |
| 42 | + let registration = registration(for: productType, with: name) |
| 43 | + let product = await registration?.factory.makeAsync(self) |
| 44 | + return product |
| 45 | + } |
| 46 | + |
| 47 | + func registration<Product>(for productType: Product.Type, with name: String?) -> FactoryRegistration<Product>? { |
| 48 | + let factoryKey = FactoryKey(productType: productType, name: name) |
| 49 | + let registration = factories.getValue(for: factoryKey) as? FactoryRegistration<Product> |
| 50 | + return registration |
| 51 | + } |
| 52 | +} |
0 commit comments