Skip to content

Commit fe8d1e7

Browse files
author
Michael Long
committed
Fix issue with caching named instances.
1 parent 9b528e6 commit fe8d1e7

File tree

2 files changed

+33
-52
lines changed

2 files changed

+33
-52
lines changed

Resolver/ResolverTests/ResolverNameTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ class ResolverNameTests: XCTestCase {
7777

7878
let base: XYZNameService? = resolver.optional()
7979

80-
XCTAssertNotNil(base)
81-
XCTAssert(base?.name == "Fred" || base?.name == "Barney")
80+
XCTAssertNil(base)
8281
}
8382

8483
}

Sources/Resolver.swift

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -125,24 +125,14 @@ public final class Resolver {
125125
public final func register<Service>(_ type: Service.Type = Service.self, name: String? = nil,
126126
factory: @escaping ResolverFactoryArguments<Service>) -> ResolverOptions<Service> {
127127
let key = ObjectIdentifier(Service.self).hashValue
128-
if let name = name {
129-
let registration = ResolverRegistration(resolver: self, key: key, factory: factory)
130-
if let container = registrations[key] as? ResolverRegistration<Service> {
131-
container.addRegistration(name, registration: registration)
132-
} else {
133-
let container = ResolverRegistration(resolver: self, key: key, factory: factory)
134-
container.addRegistration(name, registration: registration)
135-
registrations[key] = container
136-
}
137-
return registration
138-
} else if let registration = registrations[key] as? ResolverRegistration<Service> {
139-
registration.factory = factory
140-
return registration
128+
let registration = ResolverRegistration(resolver: self, key: key, name: name, factory: factory)
129+
if var container = registrations[key] {
130+
container[name ?? NONAME] = registration
131+
registrations[key] = container
141132
} else {
142-
let registration = ResolverRegistration(resolver: self, key: key, factory: factory)
143-
registrations[key] = registration
144-
return registration
133+
registrations[key] = [name ?? NONAME : registration]
145134
}
135+
return registration
146136
}
147137

148138
// MARK: - Service Resolution
@@ -168,7 +158,7 @@ public final class Resolver {
168158
/// - returns: Instance of specified Service.
169159
///
170160
public final func resolve<Service>(_ type: Service.Type = Service.self, name: String? = nil, args: Any? = nil) -> Service {
171-
if let registration = lookup(type, name: name),
161+
if let registration = lookup(type, name: name ?? NONAME),
172162
let service = registration.scope.resolve(resolver: self, registration: registration, args: args) {
173163
return service
174164
}
@@ -177,12 +167,12 @@ public final class Resolver {
177167
if typeName.contains("Optional<") {
178168
let message = "RESOLVER: \(typeName) not resolved. To disambiguate use resover.optional() instead of resover.resolve()."
179169
print(message)
180-
fatalError(message)
181170
}
182-
#endif
171+
#else
183172
let message = "RESOLVER: '\(Service.self):\(name ?? "")' not resolved."
184173
print(message)
185-
fatalError(message)
174+
#endif
175+
fatalError()
186176
}
187177

188178
/// Static function calls the root registry to resolve an optional Service type.
@@ -207,7 +197,7 @@ public final class Resolver {
207197
/// - returns: Instance of specified Service.
208198
///
209199
public final func optional<Service>(_ type: Service.Type = Service.self, name: String? = nil, args: Any? = nil) -> Service? {
210-
if let registration = lookup(type, name: name),
200+
if let registration = lookup(type, name: name ?? NONAME),
211201
let service = registration.scope.resolve(resolver: self, registration: registration, args: args) {
212202
return service
213203
}
@@ -218,27 +208,22 @@ public final class Resolver {
218208

219209
/// Internal function searches the current and parent registries for a ResolverRegistration<Service> that matches
220210
/// the supplied type and name.
221-
private final func lookup<Service>(_ type: Service.Type, name: String?) -> ResolverRegistration<Service>? {
211+
private final func lookup<Service>(_ type: Service.Type, name: String) -> ResolverRegistration<Service>? {
222212
if Resolver.registrationsNeeded {
223213
registerServices()
224214
}
225-
if let registration = registrations[ObjectIdentifier(Service.self).hashValue] as? ResolverRegistration<Service> {
226-
if let name = name {
227-
if let registration = registration.namedRegistrations?[name] as? ResolverRegistration<Service> {
228-
return registration
229-
}
230-
} else {
231-
return registration
232-
}
215+
if let container = registrations[ObjectIdentifier(Service.self).hashValue] {
216+
return container[name] as? ResolverRegistration<Service>
233217
}
234218
if let parent = parent, let registration = parent.lookup(type, name: name) {
235219
return registration
236220
}
237221
return nil
238222
}
239223

224+
private let NONAME = "*"
240225
private let parent: Resolver?
241-
private var registrations = [Int : Any]()
226+
private var registrations = [Int : [String : Any]]()
242227
private static var registrationsNeeded = true
243228
}
244229

@@ -328,25 +313,22 @@ public final class ResolverRegistration<Service>: ResolverOptions<Service> {
328313
// MARK: Parameters
329314

330315
public var key: Int
331-
public var namedRegistrations: [String : Any]?
316+
public var cacheKey: String
332317

333318
// MARK: Lifecycle
334319

335-
public init(resolver: Resolver, key: Int, factory: @escaping ResolverFactoryArguments<Service>) {
320+
public init(resolver: Resolver, key: Int, name: String?, factory: @escaping ResolverFactoryArguments<Service>) {
336321
self.key = key
322+
if let name = name {
323+
self.cacheKey = String(key) + ":" + name
324+
} else {
325+
self.cacheKey = String(key)
326+
}
337327
super.init(resolver: resolver, factory: factory)
338328
}
339329

340330
// MARK: Functions
341331

342-
public final func addRegistration(_ name: String, registration: Any) {
343-
if namedRegistrations == nil {
344-
namedRegistrations = [name:registration]
345-
} else {
346-
namedRegistrations?[name] = registration
347-
}
348-
}
349-
350332
public final func resolve(resolver: Resolver, args: Any?) -> Service? {
351333
if let service = factory(resolver, args) {
352334
self.mutator?(resolver, service, args)
@@ -380,20 +362,20 @@ public class ResolverScopeApplication: ResolverScope {
380362

381363
public final func resolve<Service>(resolver: Resolver, registration: ResolverRegistration<Service>, args: Any?) -> Service? {
382364
pthread_mutex_lock(&mutex)
383-
if let service = cachedServices[registration.key] as? Service {
365+
if let service = cachedServices[registration.cacheKey] as? Service {
384366
pthread_mutex_unlock(&mutex)
385367
return service
386368
}
387369
if let service = registration.resolve(resolver: resolver, args: args) {
388-
cachedServices[registration.key] = service
370+
cachedServices[registration.cacheKey] = service
389371
pthread_mutex_unlock(&mutex)
390372
return service
391373
}
392374
pthread_mutex_unlock(&mutex)
393375
return nil
394376
}
395377

396-
fileprivate var cachedServices = [Int : Any](minimumCapacity: 32)
378+
fileprivate var cachedServices = [String : Any](minimumCapacity: 32)
397379
fileprivate var mutex = pthread_mutex_t()
398380
}
399381

@@ -416,7 +398,7 @@ public final class ResolverScopeGraph: ResolverScope {
416398

417399
public final func resolve<Service>(resolver: Resolver, registration: ResolverRegistration<Service>, args: Any?) -> Service? {
418400
pthread_mutex_lock(&mutex)
419-
if let service = graph[registration.key] as? Service {
401+
if let service = graph[registration.cacheKey] as? Service {
420402
pthread_mutex_unlock(&mutex)
421403
return service
422404
}
@@ -426,13 +408,13 @@ public final class ResolverScopeGraph: ResolverScope {
426408
if resolutionDepth == 0 {
427409
graph.removeAll()
428410
} else {
429-
graph[registration.key] = service
411+
graph[registration.cacheKey] = service
430412
}
431413
pthread_mutex_unlock(&mutex)
432414
return service
433415
}
434416

435-
private var graph = [Int : Any?](minimumCapacity: 32)
417+
private var graph = [String : Any?](minimumCapacity: 32)
436418
private var resolutionDepth: Int = 0
437419
private var mutex = pthread_mutex_t()
438420
}
@@ -442,13 +424,13 @@ public final class ResolverScopeShare: ResolverScope {
442424

443425
public final func resolve<Service>(resolver: Resolver, registration: ResolverRegistration<Service>, args: Any?) -> Service? {
444426
pthread_mutex_lock(&mutex)
445-
if let service = cachedServices[registration.key]?.service as? Service {
427+
if let service = cachedServices[registration.cacheKey]?.service as? Service {
446428
pthread_mutex_unlock(&mutex)
447429
return service
448430
}
449431
if let service = registration.resolve(resolver: resolver, args: args) {
450432
if Service.self is AnyClass {
451-
cachedServices[registration.key] = BoxWeak(service: service as AnyObject)
433+
cachedServices[registration.cacheKey] = BoxWeak(service: service as AnyObject)
452434
}
453435
pthread_mutex_unlock(&mutex)
454436
return service
@@ -461,7 +443,7 @@ public final class ResolverScopeShare: ResolverScope {
461443
weak var service: AnyObject?
462444
}
463445

464-
private var cachedServices = [Int : BoxWeak](minimumCapacity: 32)
446+
private var cachedServices = [String : BoxWeak](minimumCapacity: 32)
465447
private var mutex = pthread_mutex_t()
466448
}
467449

0 commit comments

Comments
 (0)