Weaver
Weaver copied to clipboard
Fix dependency resolver ordering
This makes a change to how we manage the _dynamicResolvers array.
The old code popped from the front:
fileprivate static func _popDynamicResolver<Resolver>(_ resolverType: Resolver.Type) -> Resolver {
guard let dynamicResolver = _dynamicResolvers.removeFirst() as? Resolver else {
MainDependencyContainer.fatalError()
}
return dynamicResolver
}
And I've updated this to pop from the back:
fileprivate static func _popDynamicResolver<Resolver>(_ resolverType: Resolver.Type) -> Resolver {
guard let dynamicResolver = _dynamicResolvers.removeLast() as? Resolver else {
MainDependencyContainer.fatalError()
}
return dynamicResolver
}
And to support this, I've inverted the ordering of how the dependencies are pushed.
Here's the use case of the Repository class being built
_builders["repository"] = Provider.lazyBuilder(
{ (_: Optional<Provider.ParametersCopier>) -> RepositoryProtocol in
defer { MainDependencyContainer._dynamicResolversLock.unlock() }
MainDependencyContainer._dynamicResolversLock.lock()
let _inputContainer = MainDependencyContainer(provider: _inputProvider)
let __self = _inputContainer.repositoryDependencyResolver()
return Repository(injecting: __self)
}
)
This calls the function repositoryDependencyResolver() which pushes the dependency resolvers. To make sure we pop these off the stack correctly, we push them on in reverse order (so the first one we attempt to access is on the end).
Here's a look at the changes to the repositoryDependencyResolver() function...
Old:
private func repositoryDependencyResolver() -> RepositoryDependencyResolver {
let _self = MainDependencyContainer()
var _builders = Dictionary<String, Any>()
_builders["repositoryExampleSubClass"] = repositoryExampleSubClassBuilder
_builders["service"] = serviceBuilder
_builders["service2"] = service2Builder
_self.provider.addBuilders(_builders)
MainDependencyContainer._pushDynamicResolver({ _self.service })
MainDependencyContainer._pushDynamicResolver({ _self.service2 })
MainDependencyContainer._pushDynamicResolver({ _self.repositoryExampleSubClass })
return _self
}
New:
private func repositoryDependencyResolver() -> RepositoryDependencyResolver {
let _self = MainDependencyContainer()
var _builders = Dictionary<String, Any>()
_builders["repositoryExampleSubClass"] = repositoryExampleSubClassBuilder
_builders["service"] = serviceBuilder
_builders["service2"] = service2Builder
_self.provider.addBuilders(_builders)
MainDependencyContainer._pushDynamicResolver({ _self.repositoryExampleSubClass })
MainDependencyContainer._pushDynamicResolver({ _self.service2 })
MainDependencyContainer._pushDynamicResolver({ _self.service })
return _self
}