@@ -46,10 +46,6 @@ class ClientImp: Client {
46
46
*/
47
47
public final class Injected < T> : _InjectedPropertyBox {
48
48
49
- static var tag : DependencyContainer . Tag {
50
- return . String( " \( Injected< T> . self ) " )
51
- }
52
-
53
49
var _value : Any ?
54
50
55
51
public var value : T ? {
@@ -61,7 +57,11 @@ public final class Injected<T>: _InjectedPropertyBox {
61
57
}
62
58
}
63
59
64
- public init ( ) { }
60
+ var tag : DependencyContainer . Tag ?
61
+
62
+ public init ( tag: DependencyContainer . Tag ? = nil ) {
63
+ self . tag = tag
64
+ }
65
65
66
66
}
67
67
@@ -101,10 +101,6 @@ public final class InjectedWeak<T>: _InjectedWeakPropertyBox {
101
101
//so we just rely on user reading documentation and passing AnyObject in runtime
102
102
//also we will throw fatal error if type can not be casted to AnyObject during resolution
103
103
104
- static var tag : DependencyContainer . Tag {
105
- return . String( " \( InjectedWeak< T> . self ) " )
106
- }
107
-
108
104
weak var _value : AnyObject ?
109
105
110
106
public var value : T ? {
@@ -116,7 +112,11 @@ public final class InjectedWeak<T>: _InjectedWeakPropertyBox {
116
112
}
117
113
}
118
114
119
- public init ( ) { }
115
+ var tag : DependencyContainer . Tag ?
116
+
117
+ public init ( tag: DependencyContainer . Tag ? = nil ) {
118
+ self . tag = tag
119
+ }
120
120
121
121
}
122
122
@@ -166,60 +166,88 @@ typealias InjectedWeakFactory = ()->AnyObject
166
166
167
167
extension DependencyContainer {
168
168
169
- func registerInjected( definition: AutoInjectedDefinition ) {
170
- guard let key = definition. injectedKey,
171
- definition = definition. injectedDefinition else { return }
172
- definitions [ key] = definition
169
+ func registerInjected( definition: AutoInjectedDefinition , tag : Tag ? ) {
170
+ guard let key = definition. injectedKey ( tag ) ,
171
+ definitionToInject = definition. injectedDefinition else { return }
172
+ definitions [ key] = definitionToInject
173
173
}
174
174
175
- func registerInjectedWeak( definition: AutoInjectedDefinition ) {
176
- guard let key = definition. injectedWeakKey,
177
- definition = definition. injectedWeakDefinition else { return }
178
- definitions [ key] = definition
175
+ func registerInjectedWeak( definition: AutoInjectedDefinition , tag : Tag ? ) {
176
+ guard let key = definition. injectedWeakKey ( tag ) ,
177
+ definitionToInject = definition. injectedWeakDefinition else { return }
178
+ definitions [ key] = definitionToInject
179
179
}
180
180
181
- func removeInjected( definition: AutoInjectedDefinition ) {
181
+ func removeInjected( definition: AutoInjectedDefinition , tag : Tag ? ) {
182
182
guard definition. injectedDefinition != nil else { return }
183
- definitions [ definition. injectedKey] = nil
183
+ let key = definition. injectedKey ( tag)
184
+ definitions [ key] = nil
184
185
}
185
186
186
- func removeInjectedWeak( definition: AutoInjectedDefinition ) {
187
+ func removeInjectedWeak( definition: AutoInjectedDefinition , tag : Tag ? ) {
187
188
guard definition. injectedWeakDefinition != nil else { return }
188
- definitions [ definition. injectedWeakKey] = nil
189
+ let key = definition. injectedWeakKey ( tag)
190
+ definitions [ key] = nil
189
191
}
190
192
191
193
}
192
194
193
- protocol _AutoInjectedPropertyBox {
195
+ protocol _AutoInjectedPropertyBox : class {
194
196
func resolve( container: DependencyContainer ) throws
195
- static var tag : DependencyContainer . Tag { get }
197
+ var tag : DependencyContainer . Tag ? { get }
198
+ static func tagForTag( tag: DependencyContainer . Tag ? ) -> DependencyContainer . Tag
199
+ }
200
+
201
+ extension _AutoInjectedPropertyBox {
202
+
203
+ static func tagForTag( tag: DependencyContainer . Tag ? ) -> DependencyContainer . Tag {
204
+ return . String( String ( self ) ) + tag
205
+ }
206
+
207
+ func _resolve< T> ( container: DependencyContainer ) throws -> T {
208
+ do {
209
+ return try container. resolve ( tag: self . dynamicType. tagForTag ( self . tag) ) as T
210
+ }
211
+ catch {
212
+ //fallback to definition with nil tag if needed
213
+ if self . tag != nil {
214
+ return try container. resolve ( tag: self . dynamicType. tagForTag ( nil ) ) as T
215
+ }
216
+ else {
217
+ //rethrow error if instance tag is already nil
218
+ throw error
219
+ }
220
+ }
221
+
222
+ }
223
+
196
224
}
197
225
198
- protocol _InjectedPropertyBox : class , _AutoInjectedPropertyBox {
226
+ protocol _InjectedPropertyBox : _AutoInjectedPropertyBox {
199
227
var _value : Any ? { get set }
200
228
}
201
229
202
230
extension _InjectedPropertyBox {
203
231
func resolve( container: DependencyContainer ) throws {
204
- self . _value = try container . resolve ( tag : self . dynamicType . tag ) as Any
232
+ self . _value = try _resolve ( container ) as Any
205
233
}
206
234
}
207
235
208
- protocol _InjectedWeakPropertyBox : class , _AutoInjectedPropertyBox {
236
+ protocol _InjectedWeakPropertyBox : _AutoInjectedPropertyBox {
209
237
weak var _value : AnyObject ? { get set }
210
238
}
211
239
212
240
extension _InjectedWeakPropertyBox {
213
241
func resolve( container: DependencyContainer ) throws {
214
- self . _value = try container . resolve ( tag : self . dynamicType . tag ) as AnyObject
242
+ self . _value = try _resolve ( container ) as AnyObject
215
243
}
216
244
}
217
245
218
246
func isInjectedTag( tag: DependencyContainer . Tag ? ) -> String ? {
219
247
guard let tag = tag else { return nil }
220
248
guard case let . String( stringTag) = tag else { return nil }
221
249
222
- return try ! stringTag. match ( " ^Injected(?:Weak){0,1}< \\ ((.+) \\ )>$ " ) ? . first
250
+ return try ! stringTag. match ( " ^Injected(?:Weak){0,1}< \\ ((.+) \\ )>.* $ " ) ? . first
223
251
}
224
252
225
253
extension String {
@@ -238,4 +266,30 @@ extension String {
238
266
}
239
267
}
240
268
269
+ func + ( lhs: DependencyContainer . Tag , rhs: DependencyContainer . Tag ? ) -> DependencyContainer . Tag {
270
+ guard let rhs = rhs else { return lhs }
271
+ return lhs + rhs
272
+ }
273
+
274
+ func + ( lhs: DependencyContainer . Tag ? , rhs: DependencyContainer . Tag ) -> DependencyContainer . Tag {
275
+ guard let lhs = lhs else { return rhs }
276
+ return lhs + rhs
277
+ }
278
+
279
+ func + ( lhs: DependencyContainer . Tag , rhs: DependencyContainer . Tag ) -> DependencyContainer . Tag {
280
+ let lhsValue : String
281
+ switch lhs {
282
+ case let . String( stringValue) : lhsValue = stringValue
283
+ case let . Int( intValue) : lhsValue = String ( intValue)
284
+ }
285
+
286
+ let rhsValue : String
287
+ switch rhs {
288
+ case let . String( stringValue) : rhsValue = stringValue
289
+ case let . Int( intValue) : rhsValue = String ( intValue)
290
+ }
291
+
292
+ return . String( " \( lhsValue) ; \( rhsValue) " )
293
+ }
294
+
241
295
0 commit comments