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.
124 lines
5.0 KiB
124 lines
5.0 KiB
//
|
|
// Copyright © 2019 Swinject Contributors. All rights reserved.
|
|
//
|
|
|
|
/// The `Assembler` provides a means to build a container via `Assembly` instances.
|
|
public final class Assembler {
|
|
/// the container that each assembly will build its `Service` definitions into
|
|
private let container: Container
|
|
|
|
/// expose the container as a resolver so `Service` registration only happens within an assembly
|
|
public var resolver: Resolver {
|
|
return container
|
|
}
|
|
|
|
/// Will create an empty `Assembler`
|
|
///
|
|
/// - parameter container: the baseline container
|
|
///
|
|
public init(container: Container? = Container()) {
|
|
self.container = container!
|
|
}
|
|
|
|
/// Will create an empty `Assembler`
|
|
///
|
|
/// - parameter parentAssembler: the baseline assembler
|
|
/// - parameter defaultObjectScope: default object scope for container
|
|
/// - parameter behaviors: list of behaviors to be added to the container
|
|
public init(parentAssembler: Assembler?, defaultObjectScope: ObjectScope = .graph, behaviors: [Behavior] = []) {
|
|
container = Container(
|
|
parent: parentAssembler?.container,
|
|
defaultObjectScope: defaultObjectScope,
|
|
behaviors: behaviors
|
|
)
|
|
}
|
|
|
|
/// Will create a new `Assembler` with the given `Assembly` instances to build a `Container`
|
|
///
|
|
/// - parameter assemblies: the list of assemblies to build the container from
|
|
/// - parameter container: the baseline container
|
|
///
|
|
@available(*, deprecated, message: "Use not throwing alternative: init(_:, container:)")
|
|
public convenience init(assemblies: [Assembly], container: Container? = Container()) throws {
|
|
if let container = container {
|
|
self.init(assemblies, container: container)
|
|
} else {
|
|
self.init(assemblies)
|
|
}
|
|
}
|
|
|
|
/// Will create a new `Assembler` with the given `Assembly` instances to build a `Container`
|
|
///
|
|
/// - parameter assemblies: the list of assemblies to build the container from
|
|
/// - parameter container: the baseline container
|
|
///
|
|
public init(_ assemblies: [Assembly], container: Container = Container()) {
|
|
self.container = container
|
|
run(assemblies: assemblies)
|
|
}
|
|
|
|
/// Will create a new `Assembler` with the given `Assembly` instances to build a `Container`
|
|
///
|
|
/// - parameter assemblies: the list of assemblies to build the container from
|
|
/// - parameter parentAssembler: the baseline assembler
|
|
///
|
|
@available(*, deprecated, message: "Use not throwing alternative: init(_:, parent:)")
|
|
public convenience init(assemblies: [Assembly], parentAssembler: Assembler?) throws {
|
|
self.init(_: assemblies, parent: parentAssembler)
|
|
}
|
|
|
|
/// Will create a new `Assembler` with the given `Assembly` instances to build a `Container`
|
|
///
|
|
/// - parameter assemblies: the list of assemblies to build the container from
|
|
/// - parameter parent: the baseline assembler
|
|
/// - parameter defaultObjectScope: default object scope for container
|
|
/// - parameter behaviors: list of behaviors to be added to the container
|
|
public init(
|
|
_ assemblies: [Assembly],
|
|
parent: Assembler?,
|
|
defaultObjectScope: ObjectScope = .graph,
|
|
behaviors: [Behavior] = []
|
|
) {
|
|
container = Container(parent: parent?.container, defaultObjectScope: defaultObjectScope, behaviors: behaviors)
|
|
run(assemblies: assemblies)
|
|
}
|
|
|
|
/// Will apply the assembly to the container. This is useful if you want to lazy load an assembly into the
|
|
/// assembler's container.
|
|
///
|
|
/// If this assembly type is load aware, the loaded hook will be invoked right after the container has assembled
|
|
/// since after each call to `addAssembly` the container is fully loaded in its current state. If you wish to
|
|
/// lazy load several assemblies that have interdependencies between each other use `appyAssemblies`
|
|
///
|
|
/// - parameter assembly: the assembly to apply to the container
|
|
///
|
|
public func apply(assembly: Assembly) {
|
|
run(assemblies: [assembly])
|
|
}
|
|
|
|
/// Will apply the assemblies to the container. This is useful if you want to lazy load several assemblies into the
|
|
/// assembler's container
|
|
///
|
|
/// If this assembly type is load aware, the loaded hook will be invoked right after the container has assembled
|
|
/// since after each call to `addAssembly` the container is fully loaded in its current state.
|
|
///
|
|
/// - parameter assemblies: the assemblies to apply to the container
|
|
///
|
|
public func apply(assemblies: [Assembly]) {
|
|
run(assemblies: assemblies)
|
|
}
|
|
|
|
// MARK: Private
|
|
|
|
private func run(assemblies: [Assembly]) {
|
|
// build the container from each assembly
|
|
for assembly in assemblies {
|
|
assembly.assemble(container: container)
|
|
}
|
|
|
|
// inform all of the assemblies that the container is loaded
|
|
for assembly in assemblies {
|
|
assembly.loaded(resolver: resolver)
|
|
}
|
|
}
|
|
}
|