Skip to content

Commit 75bbfd3

Browse files
author
Ilya Puchka
committed
auto-injection keys encapsulated in definition
1 parent 1377a9b commit 75bbfd3

File tree

3 files changed

+66
-52
lines changed

3 files changed

+66
-52
lines changed

Dip/Dip/AutoInjection.swift

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,36 +157,31 @@ extension DependencyContainer {
157157

158158
//MARK: - Private
159159

160+
typealias InjectedFactory = ()->Any
161+
typealias InjectedWeakFactory = ()->AnyObject
162+
160163
extension DependencyContainer {
161-
typealias InjectedFactory = ()->Any
162-
typealias InjectedWeakFactory = ()->AnyObject
163-
164-
static func injectedKey<T>(type: T.Type) -> DefinitionKey {
165-
return DefinitionKey(protocolType: Any.self, factoryType: InjectedFactory.self, associatedTag: Injected<T>.tag)
166-
}
167-
168-
static func injectedWeakKey<T>(type: T.Type) -> DefinitionKey {
169-
return DefinitionKey(protocolType: AnyObject.self, factoryType: InjectedWeakFactory.self, associatedTag: InjectedWeak<T>.tag)
170-
}
171164

172-
func registerInjected<T, F>(definition: DefinitionOf<T, F>) {
173-
guard let definition = definition.injectedDefinition else { return }
174-
definitions[DependencyContainer.injectedKey(T.self)] = definition
165+
func registerInjected(definition: Definition) {
166+
guard let key = definition.injectedKey,
167+
definition = definition.injectedDefinition else { return }
168+
definitions[key] = definition
175169
}
176170

177-
func registerInjectedWeak<T, F>(definition: DefinitionOf<T, F>) {
178-
guard let definition = definition.injectedWeakDefinition else { return }
179-
definitions[DependencyContainer.injectedWeakKey(T.self)] = definition
171+
func registerInjectedWeak(definition: Definition) {
172+
guard let key = definition.injectedWeakKey,
173+
definition = definition.injectedWeakDefinition else { return }
174+
definitions[key] = definition
180175
}
181176

182-
func removeInjected<T, F>(definition: DefinitionOf<T, F>) {
177+
func removeInjected(definition: Definition) {
183178
guard definition.injectedDefinition != nil else { return }
184-
definitions[DependencyContainer.injectedKey(T.self)] = nil
179+
definitions[definition.injectedKey] = nil
185180
}
186181

187-
func removeInjectedWeak<T, F>(definition: DefinitionOf<T, F>) {
182+
func removeInjectedWeak(definition: Definition) {
188183
guard definition.injectedWeakDefinition != nil else { return }
189-
definitions[DependencyContainer.injectedWeakKey(T.self)] = nil
184+
definitions[definition.injectedWeakKey] = nil
190185
}
191186

192187
}

Dip/Dip/Definition.swift

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ struct DefinitionKey : Hashable, Equatable, CustomDebugStringConvertible {
2828
var factoryType: Any.Type
2929
var associatedTag: DependencyContainer.Tag?
3030

31+
init(protocolType: Any.Type, factoryType: Any.Type, associatedTag: DependencyContainer.Tag? = nil) {
32+
self.protocolType = protocolType
33+
self.factoryType = factoryType
34+
self.associatedTag = associatedTag
35+
}
36+
3137
var hashValue: Int {
3238
return "\(protocolType)-\(factoryType)-\(associatedTag)".hashValue
3339
}
@@ -94,27 +100,33 @@ public final class DefinitionOf<T, F>: Definition {
94100
return self
95101
}
96102

97-
let factory: F
98-
var scope: ComponentScope
99-
var resolveDependenciesBlock: ((DependencyContainer, T) -> ())?
100-
let tag: DependencyContainer.Tag?
103+
private(set) var factory: F
104+
private(set) var scope: ComponentScope = .Prototype
101105

102-
init(factory: F, scope: ComponentScope, tag: DependencyContainer.Tag?) {
106+
private(set) var resolveDependenciesBlock: ((DependencyContainer, T) -> ())?
107+
108+
private init(factory: F) {
103109
self.factory = factory
110+
}
111+
112+
public convenience init(scope: ComponentScope, factory: F) {
113+
self.init(factory: factory)
104114
self.scope = scope
105-
self.tag = tag
106115

107-
if let factory = factory as? ()->T where tag == nil {
108-
injectedDefinition = DefinitionOf<Any, ()->Any>(factory: { factory() }, scope: scope, tag: Injected<T>.tag)
116+
if let factory = factory as? ()->T {
117+
injectedDefinition = DefinitionOf<Any, ()->Any>(factory: { factory() })
118+
injectedDefinition!.scope = scope
119+
injectedKey = DefinitionKey(protocolType: Any.self, factoryType: InjectedFactory.self, associatedTag: Injected<T>.tag)
109120

110121
injectedWeakDefinition = DefinitionOf<AnyObject, ()->AnyObject>(factory: {
111122
guard let result = factory() as? AnyObject else {
112123
fatalError("\(T.self) can not be casted to AnyObject. InjectedWeak wrapper should be used to wrap only classes.")
113124
}
114125
return result
115-
}, scope: scope, tag: InjectedWeak<T>.tag)
126+
})
127+
injectedWeakDefinition!.scope = scope
128+
injectedWeakKey = DefinitionKey(protocolType: AnyObject.self, factoryType: InjectedWeakFactory.self, associatedTag: InjectedWeak<T>.tag)
116129
}
117-
118130
}
119131

120132
///Will be stored only if scope is `Singleton`
@@ -138,12 +150,20 @@ public final class DefinitionOf<T, F>: Definition {
138150
private var _resolvedInstance: T?
139151

140152
///Accessory definition used to auto-inject strong properties
141-
var injectedDefinition: DefinitionOf<Any,()->Any>?
153+
private(set) var injectedDefinition: DefinitionOf<Any,()->Any>?
154+
private(set) var injectedKey: DefinitionKey?
142155

143156
///Accessory definition used to auto-inject weak properties
144-
var injectedWeakDefinition: DefinitionOf<AnyObject,()->AnyObject>?
157+
private(set) var injectedWeakDefinition: DefinitionOf<AnyObject,()->AnyObject>?
158+
private(set) var injectedWeakKey: DefinitionKey?
145159

146160
}
147161

148162
///Dummy protocol to store definitions for different types in collection
149-
protocol Definition {}
163+
protocol Definition: class {
164+
var injectedDefinition: DefinitionOf<Any,()->Any>? { get }
165+
var injectedKey: DefinitionKey? { get }
166+
167+
var injectedWeakDefinition: DefinitionOf<AnyObject,()->AnyObject>? { get }
168+
var injectedWeakKey: DefinitionKey? { get }
169+
}

Dip/Dip/Dip.swift

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public class DependencyContainer {
6565
- parameter tag: tag used to register definition
6666
- parameter definition: definition to remove
6767
*/
68-
public func remove<T, F>(definition: DefinitionOf<T, F>) {
69-
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: definition.tag)
68+
public func remove<T, F>(definition: DefinitionOf<T, F>, forTag tag: Tag? = nil) {
69+
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: tag)
7070
definitions[key] = nil
7171
removeInjected(definition)
7272
removeInjectedWeak(definition)
@@ -145,13 +145,8 @@ public class DependencyContainer {
145145

146146
*/
147147
public func registerFactory<T, F>(tag tag: Tag? = nil, scope: ComponentScope, factory: F) -> DefinitionOf<T, F> {
148-
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: tag)
149-
let definition = DefinitionOf<T, F>(factory: factory, scope: scope, tag: tag)
150-
definitions[key] = definition
151-
152-
registerInjected(definition)
153-
registerInjectedWeak(definition)
154-
148+
let definition = DefinitionOf<T, F>(scope: scope, factory: factory)
149+
register(definition, forTag: tag)
155150
return definition
156151
}
157152

@@ -162,12 +157,14 @@ public class DependencyContainer {
162157
- parameter tag: The arbitrary tag to associate definition with
163158
- parameter definition: definition to register in container
164159
*/
165-
public func register<T, F>(definition: DefinitionOf<T, F>) {
166-
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: definition.tag)
160+
public func register<T, F>(definition: DefinitionOf<T, F>, forTag tag: Tag? = nil) {
161+
let key = DefinitionKey(protocolType: T.self, factoryType: F.self, associatedTag: tag)
167162
definitions[key] = definition
168163

169-
registerInjected(definition)
170-
registerInjectedWeak(definition)
164+
if tag == nil {
165+
registerInjected(definition)
166+
registerInjectedWeak(definition)
167+
}
171168
}
172169

173170
// MARK: Resolve dependencies
@@ -231,7 +228,7 @@ public class DependencyContainer {
231228
return resolvedInstances.resolve {
232229

233230
if let previouslyResolved: T = resolvedInstances.previouslyResolved(key, definition: definition) {
234-
resolvedInstances.storeResolvedInstance(previouslyResolved, forKey: key)
231+
resolvedInstances.storeResolvedInstance(previouslyResolved, forKey: key, definition: definition)
235232
return previouslyResolved
236233
}
237234
else {
@@ -241,11 +238,11 @@ public class DependencyContainer {
241238
//when it returns instance that we try to resolve here can be already resolved
242239
//so we return it, throwing away instance created by previous call to builder
243240
if let previouslyResolved: T = resolvedInstances.previouslyResolved(key, definition: definition) {
244-
resolvedInstances.storeResolvedInstance(previouslyResolved, forKey: key)
241+
resolvedInstances.storeResolvedInstance(previouslyResolved, forKey: key, definition: definition)
245242
return previouslyResolved
246243
}
247244

248-
resolvedInstances.storeResolvedInstance(resolvedInstance, forKey: key)
245+
resolvedInstances.storeResolvedInstance(resolvedInstance, forKey: key, definition: definition)
249246
definition.resolvedInstance = resolvedInstance
250247
definition.resolveDependenciesBlock?(self, resolvedInstance)
251248
resolveDependencies(resolvedInstance)
@@ -265,10 +262,12 @@ public class DependencyContainer {
265262
class ResolvedInstances {
266263
var resolvedInstances = [DefinitionKey: Any]()
267264

268-
func storeResolvedInstance<T>(instance: T, forKey key: DefinitionKey?) {
265+
func storeResolvedInstance<T, F>(instance: T, forKey key: DefinitionKey?, definition: DefinitionOf<T, F>) {
269266
resolvedInstances[key] = instance
270-
resolvedInstances[DependencyContainer.injectedKey(T.self)] = instance
271-
resolvedInstances[DependencyContainer.injectedWeakKey(T.self)] = instance
267+
if key != nil {
268+
resolvedInstances[definition.injectedKey] = instance
269+
resolvedInstances[definition.injectedWeakKey] = instance
270+
}
272271
}
273272

274273
func previouslyResolved<T, F>(key: DefinitionKey?, definition: DefinitionOf<T, F>) -> T? {

0 commit comments

Comments
 (0)