Collegare i livelli senza un framework DI
Comporre gli oggetti nel punto di ingresso dell’app usando il pattern Composition Root.
Collegare i livelli senza un framework DI è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 4 lezioni in totale.
Composition Root
Il Composition Root è l'unico punto in cui tutti gli oggetti vengono istanziati e collegati tra loro. In un'app SwiftUI, in genere corrisponde a @main.
@main
struct MyApp: App {
// All wiring happens here
private let container = AppContainer()
var body: some Scene {
WindowGroup { container.makeRootView() }
}
}Pattern AppContainer
Una struct/classe AppContainer costruisce il grafo degli oggetti, nascondendo la complessità dei collegamenti alla struct App.
final class AppContainer {
let db = SQLiteDatabase()
lazy var userRepo: UserRepository = RemoteUserRepository(db: db)
lazy var fetchUser = FetchUserUseCase(repo: userRepo)
lazy var profileVM = ProfileViewModel(useCase: fetchUser)
func makeRootView() -> some View { ProfileView(viewModel: profileVM) }
}Proprietà lazy per l'ordine di costruzione
Usare proprietà lazy per assicurarsi che le dipendenze vengano costruite nell'ordine corretto senza doverlo gestire manualmente.
final class Container {
lazy var network: NetworkClient = URLSessionClient()
lazy var api: APIService = APIService(client: network) // created after network
lazy var repo: ItemRepository = RemoteItemRepository(api: api)
}Metodi factory
Aggiungere metodi factory al container per creare oggetti a livello di vista con dipendenze specifiche per ogni schermata.
extension AppContainer {
func makeOrderFlow() -> OrderFlowView {
let repo = RemoteOrderRepository(api: api)
let useCase = PlaceOrderUseCase(repo: repo)
let vm = OrderViewModel(useCase: useCase)
return OrderFlowView(viewModel: vm)
}
}Environment Values per l'injection
In SwiftUI, usare EnvironmentKey personalizzati per inserire dipendenze in profondità nell'albero delle viste senza doverle passare attraverso ogni livello.
private struct FetchUserKey: EnvironmentKey {
static let defaultValue: FetchingUser = FetchUserUseCase(repo: NullUserRepo())
}
extension EnvironmentValues {
var fetchUser: FetchingUser {
get { self[FetchUserKey.self] } set { self[FetchUserKey.self] = newValue }
}
}Utilizzo dell'Environment Key
Inserire la dipendenza con .environment(\.fetchUser, container.fetchUser) e leggerla nelle viste con @Environment(\.fetchUser).
ContentView()
.environment(\.fetchUser, container.fetchUser)
// In a deep view:
@Environment(\.fetchUser) private var fetchUserContainer con ambito
Creare container figli per gli ambiti delle funzionalità, ereditando le dipendenze condivise e gestendo quelle specifiche della funzionalità.
final class CheckoutContainer {
let cart: CartRepository
let payment: PaymentService
lazy var placeOrder = PlaceOrderUseCase(cart: cart, payment: payment)
init(parent: AppContainer) {
cart = parent.cartRepo
payment = parent.paymentService
}
}Test del Composition Root
Testare i metodi factory del container verificando che gli oggetti restituiti abbiano il tipo e la configurazione corretti.
func testContainerBuildsProfileView() {
let container = AppContainer(db: InMemoryDatabase())
let view = container.makeRootView()
XCTAssertTrue(type(of: view) == ProfileView.self)
}Come evitare le dipendenze circolari
Se A dipende da B e B dipende da A, introdurre un mediator o riorganizzare le responsabilità per interrompere il ciclo.
// Circular:
// UserService → NotificationService → UserService
// Fix: UserService → NotificationInput (protocol) ← NotificationServiceQuando ricorrere a un framework DI
Il collegamento manuale si adatta bene alle app di medie dimensioni. Valutare framework come Needle e Swinject solo quando il container diventa troppo grande da gestire.
// Manual: fine for <20 top-level dependencies
// Framework: helps with large teams, 50+ services, code-generation for factoriesEsempio riepilogativo
Esempio completo di collegamento in una piccola app: il container costruisce tutte le dipendenze e una factory produce la vista radice.
final class AppContainer {
private let db = CoreDataStack.shared
lazy var userRepo: UserRepository = LocalUserRepository(db: db)
lazy var fetchUser = FetchUserUseCase(repo: userRepo)
func makeContentView() -> ContentView {
ContentView(viewModel: ProfileViewModel(useCase: fetchUser))
}
}Verifica rapida
Che cos'è il Composition Root in un'app Swift?
Riepilogo della lezione
Configurare l'app in un Composition Root (in genere @main). Usare un AppContainer con proprietà lazy per garantire il corretto ordine di costruzione. Aggiungere metodi factory per i grafi specifici di ogni schermata. Inserire le dipendenze profonde tramite EnvironmentKey personalizzati. Interrompere le dipendenze circolari con protocolli mediator.
Domande Frequenti
La lezione «Collegare i livelli senza un framework DI» è gratuita?
Sì — il testo completo di «Collegare i livelli senza un framework DI» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 4 lezioni in totale.
Cosa imparerò in «Collegare i livelli senza un framework DI»?
Comporre gli oggetti nel punto di ingresso dell’app usando il pattern Composition Root. Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Swift Academy?
Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Collegare i livelli senza un framework DI»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Swift Academy?
Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Livelli: dominio, dati e presentazione
- Pattern Use Case e Repository
- Inversione delle dipendenze con astrazioni basate su protocolli
- Collegare i livelli senza un framework DI