Varför dependency injection
Separera konstruktion från användning för bättre testbarhet.
Varför dependency injection är en gratis lektion i Swift Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Swift Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Swift Academy innehåller totalt 4 lektioner.
Varför beroendeinjektion
Beroendeinjektion (DI) innebär att ett objekt får det det behöver utifrån, i stället för att skapa det själv. Det minskar kopplingen mellan komponenter och gör dem enklare att testa.
Problemet: hård koppling
När en typ skapar sina egna samarbetande objekt blir den bunden till de konkreta klasserna och kan inte konfigureras om eller testas isolerat.
class Logger {
func log(_ m: String) { print("LOG: \(m)") }
}
class Service {
let logger = Logger() // hard-coded dependency
func run() { logger.log("running") }
}
Service().run()Koppling försvårar testning
Eftersom Service alltid skapar en riktig Logger kan ett test inte fånga upp eller ersätta loggutdata. Beroendet är osynligt utifrån.
class Logger { func log(_ m: String) { print(m) } }
class Service {
let logger = Logger()
func run() { logger.log("hello") }
}
// No way to swap Logger here.
Service().run()Idén: injicera det
Skicka i stället in beroendet. Den som anropar avgör vilken implementation som ska tillhandahållas, så Service behöver inte längre känna till den.
class Logger { func log(_ m: String) { print("LOG: \(m)") } }
class Service {
let logger: Logger
init(logger: Logger) { self.logger = logger }
func run() { logger.log("running") }
}
Service(logger: Logger()).run()Fördelar med minskad koppling
Med injektion fungerar samma Service med olika loggare, både i produktion och i tester, utan att koden behöver ändras.
class Logger { var lines: [String] = []
func log(_ m: String) { lines.append(m) } }
class Service {
let logger: Logger
init(logger: Logger) { self.logger = logger }
func run() { logger.log("event") }
}
let l = Logger()
Service(logger: l).run()
print(l.lines)Enkelt ansvar
DI stödjer principen om ett enda ansvar: en typ fokuserar på sin uppgift och överlåter andra ansvarsområden till injicerade samarbetande objekt.
struct Mailer { func send(_ to: String) { print("Mail to \(to)") } }
struct SignupFlow {
let mailer: Mailer
func register(_ email: String) { mailer.send(email) }
}
SignupFlow(mailer: Mailer()).register("a@b.com")Flexibilitet
Du kan kombinera objekt på nya sätt. Ihopkopplingen sker i appens ytterkanter, vilket håller kärnan flexibel.
struct Engine { let power: Int }
struct Car {
let engine: Engine
func describe() { print("Power: \(engine.power)") }
}
Car(engine: Engine(power: 200)).describe()
Car(engine: Engine(power: 90)).describe()Tydliga beroenden
En initializer som listar sina beroenden dokumenterar exakt vad typen behöver. Dolda, självskapade beroenden döljer detta kontrakt.
struct Repo { func load() -> [Int] { [1, 2, 3] } }
struct Report {
let repo: Repo // visible dependency
func total() -> Int { repo.load().reduce(0, +) }
}
print(Report(repo: Repo()).total())Komposition framför konstruktion
DI föredrar att objekt sätts samman utifrån. En liten composition root sätter ihop objektgrafen; resten av koden tar bara emot det den behöver.
struct DB { func count() -> Int { 42 } }
struct Stats { let db: DB; func show() { print(db.count()) } }
// Composition root:
let app = Stats(db: DB())
app.show()Inte bara för stora appar
Även små program har nytta av detta: genom att injicera ett beroende kan beteendet bytas ut och avsikterna bli tydliga utan extra ramverk.
struct Clock { func now() -> Int { 12 } }
struct Greeter {
let clock: Clock
func greet() { print(clock.now() < 12 ? "Morning" : "Afternoon") }
}
Greeter(clock: Clock()).greet()Inget ramverk behövs
DI i Swift kräver inget bibliotek. Vanliga initializers och protokoll räcker. I de kommande lektionerna visas konstruktorsinjektion, protokoll och mocking.
struct Adder { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct Calc {
let adder: Adder
func run() { print(adder.add(2, 3)) }
}
Calc(adder: Adder()).run()Snabb kontroll
Vad är grundidén med beroendeinjektion?
Sammanfattning
Beroendeinjektion tillhandahåller samarbetande objekt utifrån i stället för att skapa dem internt. Det minskar kopplingen, tydliggör beroenden och möjliggör testning. I Swift behövs inget ramverk. Nästa avsnitt handlar om den vanligaste formen: konstruktorsinjektion.
Lär dig Swift med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 122
- Lektioner
- 409
Vanliga frågor
Är lektionen ”Varför dependency injection” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Swift Academy, inklusive ”Varför dependency injection”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Swift Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Varför dependency injection”?
Separera konstruktion från användning för bättre testbarhet. Ni övar på Swift Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Swift Academy?
Du behöver inga förkunskaper. Utbildningen i Swift Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Varför dependency injection”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Swift Academy-lektionen?
Ja. Varje Swift Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför dependency injection
- Constructor injection
- Protokollbaserade abstraktioner
- Mocka beroenden i tester