[Feature] Dependencies (#3)

This PR contains the work done to provide a simple dependency injection feature whenever required.

To provide further details about this work:
- [x] renamed the `Coordinator` target in the `Package` file as `Coordination`;
- [x] declared the `Dependencies` target in the `Package` file;
- [x] defined the `DependencyKey` public protocol;
- [x] implemented the `DependencyService` public service;
- [x] implemented the `Dependency` public property wrapper;

Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
2023-04-16 15:36:07 +00:00
parent 12add7bf30
commit 9c89a59d1d
15 changed files with 274 additions and 17 deletions
@@ -1,6 +1,6 @@
//
// BaseNavigationRouter.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -1,6 +1,6 @@
//
// ModalNavigationRouter.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -1,6 +1,6 @@
//
// PushNavigationRouter.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -1,6 +1,6 @@
//
// WindowRouter.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -1,6 +1,6 @@
//
// Coordinator.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -1,6 +1,6 @@
//
// Router.swift
// Coordinator
// Coordination
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
@@ -13,7 +13,7 @@ import UIKit
/// This protocol defines how view controllers will be shown and dismissed.
public protocol Router: AnyObject {
// MARK: Typealiases
// MARK: Type aliases
typealias OnDismissedClosure = () -> Void
@@ -0,0 +1,31 @@
//
// Dependency.swift
// Dependencies
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
//
/// This property wrapper provides a direct connection to the `DependencyService` service.
@propertyWrapper
public struct Dependency<D> {
// MARK: Properties
private let keyPath: WritableKeyPath<DependencyService, D>
/// This property allows direct read/write access to a defined dependency attached to a selected key path.
public var wrappedValue: D {
get { DependencyService[keyPath] }
set { DependencyService[keyPath] = newValue }
}
// MARK: Initialisers
/// Initialise the property wrapper by setting a key path to a defined dependency.
/// - Parameter keyPath: A key path to a defined dependency in the `DependencyService` service.
public init(_ keyPath: WritableKeyPath<DependencyService, D>) {
self.keyPath = keyPath
}
}
@@ -0,0 +1,22 @@
//
// DependencyKey.swift
// Dependencies
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
//
/// This protocol defines a key to use in the dependency service.
public protocol DependencyKey {
// MARK: Associated types
/// The associated type representing the type of the dependency key's value.
associatedtype Value
// MARK: Properties
/// The default value for the dependency key.
static var currentValue: Value { get set }
}
@@ -0,0 +1,28 @@
//
// DependencyService.swift
// Dependencies
//
// Created by Javier Cicchelli on 11/04/2023.
// Copyright © 2023 Röck+Cöde. All rights reserved.
//
/// This service provide write/read access to the injected dependencies.
public struct DependencyService {
// MARK: Properties
private static var current = DependencyService()
// MARK: Subscripts
public static subscript<DK: DependencyKey>(key: DK.Type) -> DK.Value {
get { key.currentValue }
set { key.currentValue = newValue }
}
public static subscript<D>(_ keyPath: WritableKeyPath<DependencyService, D>) -> D {
get { current[keyPath: keyPath] }
set { current[keyPath: keyPath] = newValue }
}
}