From 1f29ddee6031c80ade9d94ea34d46177ae427384 Mon Sep 17 00:00:00 2001 From: Marcin Iwanicki Date: Sun, 11 Aug 2024 15:24:46 +0100 Subject: [PATCH] Add some docs --- Sources/SCInject/Assembler.swift | 9 ++++++++ Sources/SCInject/Assembly.swift | 9 ++++++++ Sources/SCInject/Container.swift | 9 ++++++++ Sources/SCInject/RegisterName.swift | 1 + Sources/SCInject/Registry.swift | 34 +++++++++++++++++++++++++++++ Sources/SCInject/Resolver.swift | 21 ++++++++++++++++++ Sources/SCInject/Scope.swift | 10 +++++++++ 7 files changed, 93 insertions(+) diff --git a/Sources/SCInject/Assembler.swift b/Sources/SCInject/Assembler.swift index 04a6bf5..e52f5cf 100644 --- a/Sources/SCInject/Assembler.swift +++ b/Sources/SCInject/Assembler.swift @@ -16,13 +16,21 @@ import Foundation +/// A class responsible for assembling dependencies and providing a `Resolver` to resolve them. +/// +/// The `Assembler` class serves as a coordinator for assembling an array of `Assembly` instances, which configure and +/// register dependencies within a `Container`. +/// Once the dependencies are assembled, the `Assembler` can return a `Resolver` for resolving the dependencies. public final class Assembler { private let container: Container + /// Initializes a new Assembler with the provided Container. public init(container: Container) { self.container = container } + /// Assembles the provided list of Assembly instances, each of which is responsible for registering its dependencies + /// within the container. @discardableResult public func assemble(_ assemblies: [Assembly]) -> Assembler { for assembly in assemblies { @@ -31,6 +39,7 @@ public final class Assembler { return self } + /// Provides the `Resolver` associated with the `Container` that was assembled. public func resolver() -> Resolver { container } diff --git a/Sources/SCInject/Assembly.swift b/Sources/SCInject/Assembly.swift index 8d265ea..acd58e0 100644 --- a/Sources/SCInject/Assembly.swift +++ b/Sources/SCInject/Assembly.swift @@ -16,6 +16,15 @@ import Foundation +/// A protocol that defines a blueprint for assembling dependencies into a registry. +/// +/// Types conforming to the `Assembly` protocol are responsible for registering dependencies within a `Registry` +/// instance. +/// These dependencies can later be resolved by a `Resolver` provided by an `Assembler`. +/// +/// This protocol is typically used in conjunction with the `Assembler` class, which coordinates the assembly process +/// across multiple `Assembly` instances. public protocol Assembly { + /// Assembles and registers dependencies into the provided `Registry`. func assemble(_ registry: Registry) } diff --git a/Sources/SCInject/Container.swift b/Sources/SCInject/Container.swift index 6da7ccc..5501826 100644 --- a/Sources/SCInject/Container.swift +++ b/Sources/SCInject/Container.swift @@ -16,8 +16,17 @@ import Foundation +/// A protocol that combines `Registry` and `Resolver` functionality, representing a container that can both register +/// and resolve dependencies. public protocol Container: Registry, Resolver {} +/// A final class that implements the `Container` protocol, providing a dependency injection container with support for +/// registering and resolving dependencies. +/// The `DefaultContainer` class allows for hierarchical dependency injection with support for different scopes +/// (`transient` and `container`). +/// Dependencies can be registered with or without names, and resolved accordingly. If a dependency is not found in the +/// current container, it will attempt to resolve it from a parent container if one exists. +/// This class is thread-safe. public final class DefaultContainer: Container { private let parent: DefaultContainer? private let lock = NSRecursiveLock() diff --git a/Sources/SCInject/RegisterName.swift b/Sources/SCInject/RegisterName.swift index cbdc61a..c067836 100644 --- a/Sources/SCInject/RegisterName.swift +++ b/Sources/SCInject/RegisterName.swift @@ -16,6 +16,7 @@ import Foundation +/// A structure that represents a name used for registering and resolving dependencies in a container. public struct RegisterName: RawRepresentable, CustomStringConvertible, Hashable { public let rawValue: String diff --git a/Sources/SCInject/Registry.swift b/Sources/SCInject/Registry.swift index 4b2b6c3..5fc61f5 100644 --- a/Sources/SCInject/Registry.swift +++ b/Sources/SCInject/Registry.swift @@ -16,13 +16,47 @@ import Foundation +/// A protocol that defines an interface for registering dependencies within a container. +/// The `Registry` protocol allows the registration of dependencies with different scopes and names. +/// Implementations of this protocol are responsible for storing the provided closures that create instances of the +/// registered types. +/// These registered dependencies can later be resolved by a `Resolver`. +/// This protocol is typically implemented by dependency injection containers, such as `DefaultContainer`. public protocol Registry { + /// Registers a dependency with a transient scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, closure: @escaping (Resolver) -> T) + + /// Registers a dependency with a specified scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter scope: The scope in which the dependency should be resolved. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, _ scope: Scope, closure: @escaping (Resolver) -> T) + /// Registers a named dependency with a transient scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter name: The name associated with the dependency. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, name: String, closure: @escaping (Resolver) -> T) + + /// Registers a named dependency with a specified scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter name: The name associated with the dependency. + /// - Parameter scope: The scope in which the dependency should be resolved. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, name: String, _ scope: Scope, closure: @escaping (Resolver) -> T) + /// Registers a named dependency with a transient scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter name: The name associated with the dependency. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, name: RegisterName, closure: @escaping (Resolver) -> T) + + /// Registers a named dependency with a specified scope. + /// - Parameter type: The type of the dependency to register. + /// - Parameter name: The name associated with the dependency. + /// - Parameter scope: The scope in which the dependency should be resolved. + /// - Parameter closure: A closure that provides the instance of the dependency. func register(_ type: T.Type, name: RegisterName, _ scope: Scope, closure: @escaping (Resolver) -> T) } diff --git a/Sources/SCInject/Resolver.swift b/Sources/SCInject/Resolver.swift index 70e2d8f..587fb85 100644 --- a/Sources/SCInject/Resolver.swift +++ b/Sources/SCInject/Resolver.swift @@ -16,8 +16,29 @@ import Foundation +/// A protocol that defines an interface for resolving dependencies from a container. +/// The `Resolver` protocol allows the retrieval of dependencies that have been previously registered in a container. +/// Dependencies can be resolved by their type, and optionally by a name, if they were registered with one. +/// Implementations of this protocol are typically provided by dependency injection containers, such as +/// `DefaultContainer`. public protocol Resolver: AnyObject { + /// Resolves a dependency by its type. + /// - Parameter type: The type of the dependency to resolve. + /// - Returns: An instance of the resolved dependency. + /// - Note: The application will crash if the dependency cannot be resolved. func resolve(_ type: T.Type) -> T + + /// Resolves a named dependency by its type. + /// - Parameter type: The type of the dependency to resolve. + /// - Parameter name: The name associated with the dependency. + /// - Returns: An instance of the resolved dependency. + /// - Note: The application will crash if the dependency cannot be resolved. func resolve(_ type: T.Type, name: String) -> T + + /// Resolves a named dependency by its type. + /// - Parameter type: The type of the dependency to resolve. + /// - Parameter name: The `RegisterName` associated with the dependency. + /// - Returns: An instance of the resolved dependency. + /// - Note: The application will crash if the dependency cannot be resolved. func resolve(_ type: T.Type, name: RegisterName) -> T } diff --git a/Sources/SCInject/Scope.swift b/Sources/SCInject/Scope.swift index f40787a..d03d989 100644 --- a/Sources/SCInject/Scope.swift +++ b/Sources/SCInject/Scope.swift @@ -14,7 +14,17 @@ // limitations under the License. // +/// An enumeration that defines the scope of a dependency within a container. +/// The `Scope` enum specifies how instances of dependencies are managed within a dependency injection container. +/// It determines whether a new instance is created each time the dependency is resolved, or whether a single instance +/// is reused throughout the container's lifetime. +/// +/// - `transient`: A new instance of the dependency is created every time it is resolved. +/// - `container`: A single instance of the dependency is created and reused throughout the container's lifetime. public enum Scope { + /// A new instance of the dependency is created every time it is resolved. case transient + + /// A single instance of the dependency is created and reused throughout the container's lifetime. case container }