Skip to content

Instantly share code, notes, and snippets.

@serhiybutz
Created February 2, 2024 17:02
Show Gist options
  • Save serhiybutz/938e5b7fbeef1348d4eb7f172115cf3e to your computer and use it in GitHub Desktop.
Save serhiybutz/938e5b7fbeef1348d4eb7f172115cf3e to your computer and use it in GitHub Desktop.
Injecting dependencies by value, scenario 1
import Foundation
// MARK: - (1) Original app blob scenario:
/// We have the app blob with original code. It contains a builder to build a UI component, which contains a UIView:
/// _Note: We use enums just for namespaces._
enum AppBlob {
/// Some class that needs to be run on Main thread:
struct UIView {
init() {
dispatchPrecondition(condition: .onQueue(.main))
}
func load() {
// ...
}
}
/// The builder:
struct Builder {
func build() {
/// Do some work on a background thread, but UI-related stuff should be done on Main thread:
DispatchQueue.main.sync {
let view = UIView()
view.load()
}
}
}
}
/// Run:
do {
/// Run code on a background thread to deload Main thread:
DispatchQueue.global().async {
/// Create a builder and run it:
let builder = AppBlob.Builder()
builder.build()
}
}
// MARK: - (2) After modularization scenario:
/// Here we have modularized the constructor into some module. The only change is that we now use the configuration object to inject dependencies:
enum SomeModule {
/// The configuration object to host injected dependencies:
struct Configuration {
let view: AppBlob.UIView
}
/// The builder moved to `SomeModule`:
struct Builder {
let cfg: Configuration
func build() {
/// Do some work on a background thread, but UI-related stuff should be done on Main thread:
DispatchQueue.main.sync {
cfg.view.load()
}
}
}
}
/// Run:
do {
/// Runs code on a background thread to deload Main thread:
DispatchQueue.global().async {
/// Create a configuration object to pass dependincies to the builder:
let cfg = SomeModule.Configuration(view: AppBlob.UIView())
/// Create a builder and run it:
let builder = SomeModule.Builder(cfg: cfg)
builder.build()
}
}
// MARK: -
/// Give async code some time to complete before exiting the app:
RunLoop.current.run(until: .init(timeIntervalSinceNow: 5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment