ခဏလေး ဒီလိုပဲ စဉ်းစားကြည့်
Dependency Injection (DI) ဆိုတာ class/View ကို 'ကိုယ့်ဒီပန်ဒင့်စီတွေကို ကိုယ်တိုင် create မလုပ်ဘဲ, ပြင်ပက ပေးပို့ခံရတယ်' ဆိုတဲ့ pattern ပါ — testing/maintainability ပိုကောင်းစေပါတယ်။ SwiftUI က Hilt (Android tutorial) လို third-party DI library မလိုအပ်ဘဲ, built-in `Environment` mechanism (`.environmentObject()`, `@EnvironmentObject`) ကို ပေးထားပါတယ် — root View မှာ dependency ကို `.environmentObject(weatherApi)` လို့ inject ထားရင်, child View (nested level ဘယ်လောက်ပဲ ရှိရှိ) ကနေ `@EnvironmentObject var weatherApi: WeatherApi` လို့ ခေါ်ယူနိုင်ပါတယ်.
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
`ContentView().environmentObject(WeatherApi())` လို့ root မှာ inject ထားရင် — nested View (`WeatherScreen` → `WeatherDetailCard` → `TemperatureLabel`) ဘယ်လောက်ပဲ deep ဖြစ်ဖြစ်, `@EnvironmentObject var weatherApi: WeatherApi` လို့ ခေါ်ယူနိုင်ပါတယ် — parameter တစ်ဆင့်ချင်း manual pass (`WeatherScreen(api:) → WeatherDetailCard(api:) → ...`) ရေးစရာ မလိုတော့ပါ.
အတူတူ ကြည့်မယ်
// Root
@main
struct MyApp: App {
@StateObject private var weatherApi = WeatherApiClient()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(weatherApi)
}
}
}
// Deeply nested child — no manual parameter passing needed
struct TemperatureLabel: View {
@EnvironmentObject var weatherApi: WeatherApiClient
var body: some View {
Text("Connected: \(weatherApi.isReady)")
}
}TemperatureLabel (deeply nested) ကို parameter manual pass မလိုဘဲ weatherApi instance ကို access လုပ်နိုင်တာ တွေ့ရမည်။၅ မိနစ် စမ်းကြည့်
`WeatherApiClient` (simple ObservableObject) ကို root မှာ `.environmentObject()` ဖြင့် inject ကြည့်ပြီး, nested View level ၂-၃ ဆင့် အောက်ကနေ `@EnvironmentObject` နဲ့ ခေါ်ယူကြည့်ပါ။
သတိလေးတစ်ချက်
`@EnvironmentObject` ရဲ့ dependency ကို root မှာ inject မထားရင် compile-time error မဟုတ်ဘဲ runtime crash ဖြစ်တတ်ပါတယ် (SwiftUI Preview ထဲမှာလည်း ထပ်တူ inject ပေးထားရပါမယ်) — production build မတိုင်ခင် Preview panel ကနေတောင် ဒီ error မျိုးကို ကြိုတွေ့နိုင်ပါတယ်။