-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #93 from uber/foundation-merge_in_extension-master
Merge NeedleFoundationExtension into NeedleFoundation
- Loading branch information
Showing
6 changed files
with
505 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
...dation/Sources/NeedleFoundation/Pluginized/Internal/PluginExtensionProviderRegistry.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// | ||
// 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 dependnecy 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. | ||
/// - parameter componentPath: The dependency graph path 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` componentPath: String, _ pluginExtensionProviderFactory: @escaping (PluginizedComponentType) -> AnyObject) { | ||
// Lock on `providerFactories` access. | ||
lock.lock() | ||
defer { | ||
lock.unlock() | ||
} | ||
|
||
providerFactories[componentPath.hashValue] = pluginExtensionProviderFactory | ||
} | ||
|
||
func pluginExtensionProvider(`for` component: PluginizedComponentType) -> AnyObject { | ||
// Lock on `providerFactories` access. | ||
lock.lock() | ||
defer { | ||
lock.unlock() | ||
} | ||
|
||
if let factory = providerFactories[component.path.hashValue] { | ||
return factory(component) | ||
} else { | ||
fatalError("Missing plugin extension provider factory for \(component.path)") | ||
} | ||
} | ||
|
||
private let lock = NSRecursiveLock() | ||
private var providerFactories = [Int: (PluginizedComponentType) -> AnyObject]() | ||
|
||
private init() {} | ||
} |
74 changes: 74 additions & 0 deletions
74
Foundation/Sources/NeedleFoundation/Pluginized/NonCoreComponent.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// | ||
// 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 CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
|
||
import Foundation | ||
|
||
/// The base protocol for a non-core component defining its lifecycle to | ||
/// support scope activation and deactivation. | ||
/// | ||
/// - note: A separate protocol is used to allow `PluginizableComponent` | ||
/// to delcare a non-core component generic without having to specify the | ||
/// dependency protocol nested generics. | ||
public protocol NonCoreComponentType: AnyObject { | ||
/// Initializer. | ||
/// | ||
/// - parameter parent: The parent component of this component. | ||
init(parent: ComponentType) | ||
|
||
/// Indicate the corresponding core scope has become active, thereby | ||
/// activating this non-core component as well. | ||
/// | ||
/// - note: This method is automatically invoked when the non-core component | ||
/// is paired with a `PluginizableComponent` that is bound to a `Router`. | ||
/// Otherwise, this method must be explicitly invoked. | ||
func scopeDidBecomeActive() | ||
|
||
/// Indicate the corresponding core scope has become inactive, thereby | ||
/// deactivating this non-core component as well. | ||
/// | ||
/// - note: This method is automatically invoked when the non-core component | ||
/// is paired with a `PluginizableComponent` that is bound to a `Router`. | ||
/// Otherwise, this method must be explicitly invoked. | ||
func scopeDidBecomeInactive() | ||
} | ||
|
||
/// The base non-core component class. All non-core components should inherit | ||
/// from this class. | ||
open class NonCoreComponent<DependencyType>: Component<DependencyType>, NonCoreComponentType { | ||
|
||
/// Initializer. | ||
/// | ||
/// - parameter parent: The parent component of this component. | ||
public required override init(parent: ComponentType) { | ||
super.init(parent: parent) | ||
} | ||
|
||
/// Indicate the corresponding core scope has become active, thereby | ||
/// activating this non-core component as well. | ||
/// | ||
/// - note: This method is automatically invoked when the non-core component | ||
/// is paired with a `PluginizableComponent` that is bound to a `Router`. | ||
/// Otherwise, this method must be explicitly invoked. | ||
open func scopeDidBecomeActive() {} | ||
|
||
/// Indicate the corresponding core scope has become inactive, thereby | ||
/// deactivating this non-core component as well. | ||
/// | ||
/// - note: This method is automatically invoked when the non-core component | ||
/// is paired with a `PluginizableComponent` that is bound to a `Router`. | ||
/// Otherwise, this method must be explicitly invoked. | ||
open func scopeDidBecomeInactive() {} | ||
} |
Oops, something went wrong.