You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.6 KiB
77 lines
2.6 KiB
//
|
|
// Copyright © 2019 Swinject Contributors. All rights reserved.
|
|
//
|
|
|
|
protocol InstanceWrapper {
|
|
static var wrappedType: Any.Type { get }
|
|
init?(inContainer container: Container, withInstanceFactory factory: (() -> Any?)?)
|
|
}
|
|
|
|
/// Wrapper to enable delayed dependency instantiation.
|
|
/// `Lazy<Type>` does not need to be explicitly registered into the `Container` - resolution will work
|
|
/// as long as there is a registration for the `Type`.
|
|
public final class Lazy<Service>: InstanceWrapper {
|
|
static var wrappedType: Any.Type { return Service.self }
|
|
|
|
private let factory: () -> Any?
|
|
private let graphIdentifier: GraphIdentifier?
|
|
private weak var container: Container?
|
|
|
|
init?(inContainer container: Container, withInstanceFactory factory: (() -> Any?)?) {
|
|
guard let factory = factory else { return nil }
|
|
self.factory = factory
|
|
graphIdentifier = container.currentObjectGraph
|
|
self.container = container
|
|
}
|
|
|
|
private var _instance: Service?
|
|
|
|
/// Getter for the wrapped object.
|
|
/// It will be resolved from the `Container` when first accessed, all other calls will return the same instance.
|
|
public var instance: Service {
|
|
if let instance = _instance {
|
|
return instance
|
|
} else {
|
|
_instance = makeInstance()
|
|
return _instance!
|
|
}
|
|
}
|
|
|
|
private func makeInstance() -> Service? {
|
|
guard let container = container else {
|
|
return nil
|
|
}
|
|
if let graphIdentifier = graphIdentifier {
|
|
container.restoreObjectGraph(graphIdentifier)
|
|
}
|
|
return factory() as? Service
|
|
}
|
|
}
|
|
|
|
/// Wrapper to enable delayed dependency instantiation.
|
|
/// `Provider<Type>` does not need to be explicitly registered into the `Container` - resolution will work
|
|
/// as long as there is a registration for the `Type`.
|
|
public final class Provider<Service>: InstanceWrapper {
|
|
static var wrappedType: Any.Type { return Service.self }
|
|
|
|
private let factory: () -> Any?
|
|
|
|
init?(inContainer _: Container, withInstanceFactory factory: (() -> Any?)?) {
|
|
guard let factory = factory else { return nil }
|
|
self.factory = factory
|
|
}
|
|
|
|
/// Getter for the wrapped object.
|
|
/// New instance will be resolved from the `Container` every time it is accessed.
|
|
public var instance: Service {
|
|
return factory() as! Service
|
|
}
|
|
}
|
|
|
|
extension Optional: InstanceWrapper {
|
|
static var wrappedType: Any.Type { return Wrapped.self }
|
|
|
|
init?(inContainer _: Container, withInstanceFactory factory: (() -> Any?)?) {
|
|
self = factory?() as? Wrapped
|
|
}
|
|
}
|