-
Notifications
You must be signed in to change notification settings - Fork 0
Setting/#7 DIContainer #8
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
Changes from all commits
9ff7558
8da5831
d24faa9
5dc0bd2
2b06bf7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // | ||
| // AppDIContainer+.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/5/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| extension DIContainer { | ||
| func dependencyInjection() { | ||
| let dataDependencyAssembler = DataDependencyAssembler() | ||
| let domainDependencyAssembler = DomainDependencyAssembler(preAssembler: dataDependencyAssembler) | ||
| let presentationDependencyAssembler = PresentationDependencyAssembler(preAssembler: domainDependencyAssembler) | ||
|
|
||
| presentationDependencyAssembler.assemble() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,35 @@ | ||
| // | ||
| // DIContainer.swift | ||
| // AppDIContainer.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 12/31/25. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| protocol DependencyAssembler { | ||
| func assemble() | ||
| } | ||
|
|
||
| final class DIContainer { | ||
|
|
||
| static let shared = DIContainer() | ||
|
|
||
| private init() { } | ||
|
|
||
| private var dependencies: [String: () -> Any] = [:] | ||
|
|
||
| func register<T>(type: T.Type, closure: @escaping () -> T) { | ||
| let key = String(describing: T.self) | ||
| dependencies[key] = closure | ||
| } | ||
|
Comment on lines
+20
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add thread-safety to prevent data races. The ๐ Proposed fix using a serial queue or lock final class DIContainer {
static let shared = DIContainer()
private init() { }
+ private let queue = DispatchQueue(label: "com.cherrish.dicontainer", attributes: .concurrent)
private var dependencies: [String: () -> Any] = [:]
func register<T>(type: T.Type, closure: @escaping () -> T) {
let key = String(describing: T.self)
- dependencies[key] = closure
+ queue.async(flags: .barrier) { [weak self] in
+ self?.dependencies[key] = closure
+ }
}
func resolve<T>(type: T.Type) -> T? {
let key = String(describing: T.self)
- guard let closure = dependencies[key] else {
- return nil
- }
-
- return closure() as? T
+ return queue.sync {
+ guard let closure = dependencies[key] else {
+ return nil
+ }
+ return closure() as? T
+ }
}
}
๐ค Prompt for AI Agents |
||
|
|
||
| func resolve<T>(type: T.Type) -> T? { | ||
| let key = String(describing: T.self) | ||
| guard let closure = dependencies[key] else { | ||
| return nil | ||
| } | ||
|
|
||
| return closure() as? T | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // | ||
| // DataDependencyAssembler.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/5/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| final class DataDependencyAssembler: DependencyAssembler { | ||
| func assemble() { | ||
| DIContainer.shared.register(type: TestInterface.self) { | ||
| return DefaultTestRepository() | ||
| } | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // | ||
| // Repository.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/3/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| struct DefaultTestRepository: TestInterface { | ||
| func test() { | ||
| print("Repository Test!") | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // | ||
| // DomainDependencyAssembler.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/5/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| final class DomainDependencyAssembler: DependencyAssembler { | ||
| private let preAssembler: DependencyAssembler | ||
|
|
||
| init(preAssembler: DependencyAssembler) { | ||
| self.preAssembler = preAssembler | ||
| } | ||
|
|
||
| func assemble() { | ||
| preAssembler.assemble() | ||
|
|
||
| guard let testRepository = DIContainer.shared.resolve(type: TestInterface.self) else { | ||
| return | ||
| } | ||
|
|
||
| DIContainer.shared.register(type: TestUseCase.self) { | ||
| return DefaultTestUseCase(repository: testRepository) | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,3 +6,7 @@ | |
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| protocol TestInterface { | ||
| func test() | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // | ||
| // Usecase.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/3/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| protocol TestUseCase { | ||
| func execute() | ||
| } | ||
|
|
||
| struct DefaultTestUseCase: TestUseCase { | ||
| private let repository: TestInterface | ||
|
|
||
| init(repository: TestInterface) { | ||
| self.repository = repository | ||
| } | ||
|
|
||
| func execute() { | ||
| self.repository.test() | ||
| print("UseCase execute") | ||
| } | ||
| } |
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||||||
| // | ||||||||||
| // ContentView.swift | ||||||||||
|
Comment on lines
+1
to
+2
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the file header comment mismatch. The header comment references "ContentView.swift" but the actual file is "TestView.swift". This inconsistency can cause confusion during code navigation and maintenance. ๐ Proposed fix //
-// ContentView.swift
+// TestView.swift
// Cherrish-iOS๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||
| // Cherrish-iOS | ||||||||||
| // | ||||||||||
| // Created by ์ด๋์ฐ on 12/31/25. | ||||||||||
| // | ||||||||||
|
|
||||||||||
| import SwiftUI | ||||||||||
|
|
||||||||||
| struct TestView: View { | ||||||||||
| @ObservedObject var viewModel: TestViewModel | ||||||||||
|
|
||||||||||
| var body: some View { | ||||||||||
| VStack { | ||||||||||
| Button(action: { | ||||||||||
| viewModel.test() | ||||||||||
| }) { | ||||||||||
| Text("\(viewModel.text)") | ||||||||||
| } | ||||||||||
| .padding() | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // | ||
| // TestViewModel.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/5/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| final class TestViewModel: ObservableObject { | ||
| @Published var text: String = "ํฐ์นํด๋ณด์ธ์ฌ" | ||
| private let testUseCase: TestUseCase | ||
|
|
||
| init(testUseCase: TestUseCase) { | ||
| self.testUseCase = testUseCase | ||
| } | ||
|
|
||
| func test() { | ||
| testUseCase.execute() | ||
| text = "๋ฒํผ ํฐ์นํ์!" | ||
| print("view model execute") | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||
| // PresentationDependencyAssembler.swift | ||||||||||||||||||||||||||||||||||||||||||||
| // Cherrish-iOS | ||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||
| // Created by ์ด๋์ฐ on 1/5/26. | ||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| import Foundation | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| final class PresentationDependencyAssembler: DependencyAssembler { | ||||||||||||||||||||||||||||||||||||||||||||
| private let preAssembler: DependencyAssembler | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| init(preAssembler: DependencyAssembler) { | ||||||||||||||||||||||||||||||||||||||||||||
| self.preAssembler = preAssembler | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| func assemble() { | ||||||||||||||||||||||||||||||||||||||||||||
| preAssembler.assemble() | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| guard let testUseCase = DIContainer.shared.resolve(type: TestUseCase.self) else { | ||||||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| DIContainer.shared.register(type: TestViewModel.self) { | ||||||||||||||||||||||||||||||||||||||||||||
| print("๋ทฐ๋ชจ๋ธ ๋ฑ๋ก") | ||||||||||||||||||||||||||||||||||||||||||||
| return TestViewModel(testUseCase: testUseCase) | ||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+17
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐ ๏ธ Refactor suggestion | ๐ Major Remove debug print statement before production. The print statement on line 25 should be removed or replaced with proper logging infrastructure. Debug prints are not suitable for production code. ๐ Proposed fix DIContainer.shared.register(type: TestViewModel.self) {
- print("๋ทฐ๋ชจ๋ธ ๋ฑ๋ก")
return TestViewModel(testUseCase: testUseCase)
}๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // | ||
| // ViewFactory.swift | ||
| // Cherrish-iOS | ||
| // | ||
| // Created by ์ด๋์ฐ on 1/5/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| protocol ViewFactoryProtocol { | ||
| static func makeTestView() -> TestView | ||
| } | ||
|
|
||
| final class ViewFactory: ViewFactoryProtocol { | ||
| static func makeTestView() -> TestView { | ||
| guard let viewModel = DIContainer.shared.resolve(type: TestViewModel.self) else { | ||
| // TODO: DI ์คํจ ์ ๊ธฐ๋ณธ์ผ๋ก ๊ฐ ๊ณณ ์ง์ | ||
| fatalError() | ||
| } | ||
| return TestView(viewModel: viewModel) | ||
| } | ||
|
Comment on lines
+15
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace fatalError with graceful degradation. Using
This aligns with the TODO comment about specifying a default destination. Would you like me to generate an implementation that provides graceful degradation with proper error logging? ๐งฐ Tools๐ช SwiftLint (0.57.0)[Warning] 17-17: TODOs should be resolved (DI ์คํจ ์ ๊ธฐ๋ณธ์ผ๋ก ๊ฐ ๊ณณ ์ง์ ) (todo) ๐ค Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File name mismatch in header comment.
The header comment references "AppDIContainer+.swift" but the actual filename is "DIContainer+.swift".
๐ Proposed fix
๐ Committable suggestion
๐ค Prompt for AI Agents