Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dependency resolver ordering #169

Open
wants to merge 2 commits into
base: stephane/backup
Choose a base branch
from

Conversation

StephaneMagne
Copy link
Contributor

@StephaneMagne StephaneMagne commented Jun 9, 2022

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
    }

Stephane Magne added 2 commits June 9, 2022 14:26
…ray instead of the front. Invert the ordering of pushed resolvers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
1 participant