Skip to content

Commit

Permalink
feat: Re-added LazyInjectService InjectService for backward compatibi…
Browse files Browse the repository at this point in the history
…lity
  • Loading branch information
adrien-coye committed Aug 14, 2024
1 parent f987afb commit b7ad8dc
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 15 deletions.
14 changes: 3 additions & 11 deletions Sources/InfomaniakDI/DependencyInjectionService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,8 @@ import Foundation
/// Allows to add and remove dynamically containers.
/// Also provides a standard, shared, singleton style, container.
public final class DependencyInjectionService {

/// Shared container of all singletons of an executable
var _sharedContainer: Container

public var sharedContainer: Container {
_sharedContainer
}

public init(sharedContainer: Container = Container()) {
self._sharedContainer = sharedContainer
}

public static let sharedContainer = Container()

public init() {}
}
File renamed without changes.
77 changes: 77 additions & 0 deletions Sources/InfomaniakDI/PropertyWrappers/InjectService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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

/// A property wrapper that resolves shared types when the host type is initialized.
@propertyWrapper public struct InjectService<Injected>: CustomDebugStringConvertible, Equatable, Identifiable {
/// Identifiable
///
/// Something to link the identity of this property wrapper to the underlying Service type.
public let id = ObjectIdentifier(Injected.self)

/// Equatable
///
/// Two `InjectService` that points to the same `Injected` Metatype are expected to be equal (for the sake of SwiftUI
/// correctness)
public static func == (lhs: InjectService<Injected>, rhs: InjectService<Injected>) -> Bool {
return lhs.id == rhs.id
}

public var debugDescription: String {
"""
<\(type(of: self))
wrapping type:'\(Injected.self)'
customTypeIdentifier:\(String(describing: customTypeIdentifier))
factoryParameters:\(String(describing: factoryParameters))
id:\(id)'>
"""
}

/// Store the resolved service
var service: Injected!

public var container: Resolvable
public var customTypeIdentifier: String?
public var factoryParameters: [String: Any]?

public init(customTypeIdentifier: String? = nil,
factoryParameters: [String: Any]? = nil) {
self.customTypeIdentifier = customTypeIdentifier
self.factoryParameters = factoryParameters
container = DependencyInjectionService.sharedContainer

do {
service = try container.resolve(type: Injected.self,
forCustomTypeIdentifier: customTypeIdentifier,
factoryParameters: factoryParameters,
resolver: container)
} catch {
fatalError("DI fatal error :\(error)")
}
}

public var wrappedValue: Injected {
get {
service
}
set {
fatalError("You are not expected to substitute resolved objects")
}
}

/// The property wrapper itself for debugging and testing
public var projectedValue: Self {
self
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import Foundation

/// Inject a type at the first use of the property
@propertyWrapper public final class LazyInject<Injected>: Equatable, Identifiable {
@propertyWrapper public class LazyInject<Injected>: Equatable, Identifiable {
/// Identifiable
///
/// Something to link the identity of this property wrapper to the underlying Service type.
Expand Down Expand Up @@ -61,9 +61,9 @@ import Foundation

do {
resolvedInstance = try container.resolve(type: Injected.self,
forCustomTypeIdentifier: customTypeIdentifier,
factoryParameters: factoryParameters,
resolver: container)
forCustomTypeIdentifier: customTypeIdentifier,
factoryParameters: factoryParameters,
resolver: container)
return resolvedInstance!
} catch {
fatalError("DI fatal error :\(error)")
Expand Down
79 changes: 79 additions & 0 deletions Sources/InfomaniakDI/PropertyWrappers/LazyInjectService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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

@propertyWrapper public class LazyInjectService<Injected>: Equatable, Identifiable {
/// Identifiable
///
/// Something to link the identity of this property wrapper to the underlying Service type.
public let id = ObjectIdentifier(Injected.self)

/// Equatable
///
/// Two `LazyInjectService` that points to the same `Service` Metatype are expected to be equal (for the sake of SwiftUI
/// correctness)
public static func == (lhs: LazyInjectService<Injected>, rhs: LazyInjectService<Injected>) -> Bool {
return lhs.id == rhs.id
}

public var debugDescription: String {
"""
<\(type(of: self))
wrapping type:'\(Injected.self)'
customTypeIdentifier:\(String(describing: customTypeIdentifier))
factoryParameters:\(String(describing: factoryParameters))
id:\(id)'>
"""
}

/// Store the instance of the resolved type
var resolvedInstance: Injected?

public var container: Resolvable
public var customTypeIdentifier: String?
public var factoryParameters: [String: Any]?

public init(customTypeIdentifier: String? = nil,
factoryParameters: [String: Any]? = nil) {
self.customTypeIdentifier = customTypeIdentifier
self.factoryParameters = factoryParameters
container = DependencyInjectionService.sharedContainer
}

public var wrappedValue: Injected {
get {
if let resolvedInstance {
return resolvedInstance
}

do {
resolvedInstance = try container.resolve(type: Injected.self,
forCustomTypeIdentifier: customTypeIdentifier,
factoryParameters: factoryParameters,
resolver: container)
return resolvedInstance!
} catch {
fatalError("DI fatal error :\(error)")
}
}
set {
fatalError("You are not expected to substitute resolved objects")
}
}

/// The property wrapper itself for debugging and testing
public var projectedValue: LazyInjectService {
self
}
}

0 comments on commit b7ad8dc

Please sign in to comment.