-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDIContainer.swift
More file actions
105 lines (84 loc) · 2.69 KB
/
Copy pathDIContainer.swift
File metadata and controls
105 lines (84 loc) · 2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//
// DIContainer.swift
// DevLogCore
//
// Created by opfic on 5/15/26.
//
import Foundation
public struct DependencyName: Hashable, ExpressibleByStringLiteral {
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(stringLiteral value: String) {
self.rawValue = value
}
}
public enum DependencyScope {
case singleton
case transient
}
public protocol DIContainer: Sendable {
func register<T>(
_ type: T.Type,
name: DependencyName?,
scope: DependencyScope,
_ factory: @escaping () -> T
)
func resolve<T>(_ type: T.Type, name: DependencyName?) -> T
}
public extension DIContainer {
func register<T>(
_ type: T.Type,
name: DependencyName? = nil,
scope: DependencyScope = .singleton,
_ factory: @escaping () -> T
) {
register(type, name: name, scope: scope, factory)
}
func resolve<T>(_ type: T.Type, name: DependencyName? = nil) -> T {
resolve(type, name: name)
}
}
public final class AppDIContainer: DIContainer, @unchecked Sendable {
public static let `default` = AppDIContainer()
private let lock = NSRecursiveLock()
private init() { }
private struct Key: Hashable {
let type: ObjectIdentifier
let name: DependencyName?
}
private struct Registration {
let scope: DependencyScope
let factory: () -> Any
}
private var registrations = [Key: Registration]()
private var singletons = [Key: Any]()
public func register<T>(
_ type: T.Type,
name: DependencyName? = nil,
scope: DependencyScope = .singleton,
_ factory: @escaping () -> T
) {
lock.lock()
defer { lock.unlock() }
let key = Key(type: .init(type), name: name)
registrations[key] = Registration(scope: scope, factory: factory)
}
public func resolve<T>(_ type: T.Type, name: DependencyName? = nil) -> T {
lock.lock()
defer { lock.unlock() }
let key = Key(type: .init(type), name: name)
guard let registration = registrations[key] else { fatalError("\(type)에 대한 의존성이 등록되지 않았습니다.") }
switch registration.scope {
case .singleton:
if let cached = singletons[key] as? T { return cached }
guard let singleton = registration.factory() as? T else { fatalError("\(type) 생성 실패") }
singletons[key] = singleton
return singleton
case .transient:
guard let resolved = registration.factory() as? T else { fatalError("\(type) 생성 실패") }
return resolved
}
}
}