Sources/NeedleFoundation/Pluginized/Internal/PluginExtensionProviderRegistry.swift (26 lines of code) (raw):

// // Copyright (c) 2018. Uber Technologies // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR COITIONS OF ANY KI, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // import Foundation /// Needle internal registry of plugin extension providers. /// - note: This class is only needed until Swift supports extensions /// overriding methods. This is an internal class to the Needle dependency /// injection framework. Application code should never use this class. // TODO: Remove this once Swift supports extension overriding methods. // Once that happens, we can declare an `open createPluginExtensionProvider` // method in the base pluginized component class. Generate extensions to // all the pluginized component subclasses that override the method to // instantiate the dependency providers. public class __PluginExtensionProviderRegistry { /// The singleton instance. public static let instance = __PluginExtensionProviderRegistry() /// Register the given factory closure with given key. /// /// - note: This method is thread-safe. /// - note: Plugin extension provider is unique per pluginized component /// regardless of its path, since it only extracts properties from its /// corresponding non-core component. /// - parameter componentName: The name of the component the provider /// is for. /// - parameter pluginExtensionProviderFactory: The closure that takes /// in a component to be injected and returns a provider instance that /// conforms to the component's plugin extensions protocol. public func registerPluginExtensionProviderFactory(`for` componentName: String, _ pluginExtensionProviderFactory: @escaping (PluginizedScope) -> AnyObject) { // Lock on `providerFactories` access. lock.lock() defer { lock.unlock() } providerFactories[componentName] = pluginExtensionProviderFactory } func pluginExtensionProvider(`for` component: PluginizedScope) -> AnyObject { // Lock on `providerFactories` access. lock.lock() defer { lock.unlock() } // The last element of the path is the component itself and it always exists. let key = component.path.last! if let factory = providerFactories[key] { return factory(component) } else { // This case should never occur with properly generated Needle code. // This is useful for Needle generator development only. fatalError("Missing plugin extension provider factory for \(component.path)") } } private let lock = NSRecursiveLock() private var providerFactories = [String: (PluginizedScope) -> AnyObject]() private init() {} }