Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining dependencies with arguments #49

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added a way to define dependencies with different arguments and same …
…result type
  • Loading branch information
brototyp committed Dec 29, 2022
commit 2a252749d68c1cda1c4c7a1833bbbd46f50c91b4
11 changes: 7 additions & 4 deletions DIKit/Sources/Component/Component.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ class Component<A, T>: ComponentProtocol {

init(lifetime: Lifetime, factory: @escaping (_ argument: A) -> T) {
self.lifetime = lifetime
self.identifier = ComponentIdentifier(type: T.self)
self.identifier = ComponentIdentifier(type: T.self, argumentType: A.self)
self.type = T.self
self.componentFactory = { factory($0 as! A) } // swiftlint:disable:this force_cast
}

init(lifetime: Lifetime, tag: AnyHashable, factory: @escaping (_ argument: A) -> T) {
self.lifetime = lifetime
self.identifier = ComponentIdentifier(tag: tag, type: T.self)
self.identifier = ComponentIdentifier(tag: tag, type: T.self, argumentType: A.self)
self.type = T.self
self.componentFactory = { factory($0 as! A) } // swiftlint:disable:this force_cast
}
Expand All @@ -33,22 +33,25 @@ class Component<A, T>: ComponentProtocol {
struct ComponentIdentifier: Hashable {
let tag: AnyHashable?
let type: Any.Type
let argumentType: Any.Type

func hash(into hasher: inout Hasher) {
hasher.combine(String(describing: type))
hasher.combine(String(describing: argumentType))
if let tag = tag {
hasher.combine(tag)
}
}

static func == (lhs: ComponentIdentifier, rhs: ComponentIdentifier) -> Bool {
lhs.type == rhs.type && lhs.tag == rhs.tag
lhs.type == rhs.type && lhs.tag == rhs.tag && lhs.argumentType == rhs.argumentType
}
}

extension ComponentIdentifier {
init(type: Any.Type) {
init(type: Any.Type, argumentType: Any.Type) {
self.type = type
self.argumentType = argumentType
self.tag = nil
}
}
Expand Down
4 changes: 2 additions & 2 deletions DIKit/Sources/Container/DependencyContainer+Resolve.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension DependencyContainer {
/// - Parameter tag: An optional *tag* to identify the Component. `nil` per default.
/// - Returns: The resolved `Optional<Component<T>>`.
func _resolve<A, T>(_ argument: A, tag: AnyHashable? = nil) -> T? {
let identifier = ComponentIdentifier(tag: tag, type: T.self)
let identifier = ComponentIdentifier(tag: tag, type: T.self, argumentType: A.self)
guard let foundComponent = self.componentStack[identifier] else {
return nil
}
Expand All @@ -37,7 +37,7 @@ extension DependencyContainer {
///
/// - Returns: `Bool` whether `Component<T>` is resolvable or not.
func resolvable<T>(type: T.Type, tag: AnyHashable? = nil) -> Bool {
let identifier = ComponentIdentifier(tag: tag, type: T.self)
let identifier = ComponentIdentifier(tag: tag, type: T.self, argumentType: Void.self)
return self.componentStack[identifier] != nil
}

Expand Down
4 changes: 3 additions & 1 deletion DIKitExample/Sources/DependencyContainer+App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public extension DependencyContainer {
factory(tag: StorageContext.systemdata) { LocalStorage(name: "system") as LocalStorageProtocol }
factory(tag: StorageContext.userdata) { LocalStorage(name: "userdata") as LocalStorageProtocol }

factory { name in LocalStorage(name: name ?? "default") as LocalStorageProtocol }
factory { LocalStorage(name: "default") as LocalStorageProtocol }
factory { name in LocalStorage(name: name) as LocalStorageProtocol }
factory { (args: (name: String, other: Int)) in LocalStorage(name: args.name) as LocalStorageProtocol }
}
}
8 changes: 6 additions & 2 deletions DIKitExample/Sources/Views/FirstViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ import DIKitExampleBackend
class FirstViewController: UIViewController {
// MARK: - DIKit
@Inject var backend: BackendProtocol
@Inject("Local Storage with a custom name") var localStorage: LocalStorageProtocol
@Inject var defaultLocalStorage: LocalStorageProtocol
@Inject("With just one parameter") var localStorageWithJustOneParameter: LocalStorageProtocol
@Inject((name: "Local Storage with multiple parameters", other: 1)) var localStorageWithMultipleParameters: LocalStorageProtocol

// MARK: - View lifecycle
override func viewWillAppear(_ animated: Bool) {
let result = backend.fetch()
print(result)

print(localStorage.name)
print(defaultLocalStorage.name)
print(localStorageWithJustOneParameter.name)
print(localStorageWithMultipleParameters.name)
}
}