Created
February 2, 2024 17:02
-
-
Save serhiybutz/938e5b7fbeef1348d4eb7f172115cf3e to your computer and use it in GitHub Desktop.
Injecting dependencies by value, scenario 1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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