Swift Academy · Oppitunti

Kerrosten yhdistäminen ilman DI-kehystä

Olioiden koostaminen sovelluksen käynnistyskohdassa Composition Root -mallilla.

Oppitunti 4/413 vaihetta

Kerrosten yhdistäminen ilman DI-kehystä on ilmainen Swift Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Swift Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Composition Root

Composition Root on ainoa paikka, jossa kaikki oliot luodaan ja kytketään toisiinsa. SwiftUI-sovelluksessa se on yleensä @main.

@main
struct MyApp: App {
  // All wiring happens here
  private let container = AppContainer()
  var body: some Scene {
    WindowGroup { container.makeRootView() }
  }
}

AppContainer-malli

AppContainer-struct tai -class rakentaa oliograafin ja piilottaa kytkentöjen monimutkaisuuden App-structilta.

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) }
}

Lazy-ominaisuudet rakennusjärjestystä varten

Käyttäkää lazy-ominaisuuksia varmistaaksenne, että riippuvuudet rakennetaan oikeassa järjestyksessä ilman manuaalista järjestelyä.

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)
}

Tehdasmetodit

Lisätkää säiliöön tehdasmetodeja, joilla luodaan näkymätason oliot näyttökohtaisine riippuvuuksineen.

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-arvot injektointiin

Käyttäkää SwiftUI:ssa mukautettuja EnvironmentKey-avaimia riippuvuuksien injektointiin syvälle näkymäpuuhun ilman prop-drillingiä.

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 }
  }
}

Environment-avaimen käyttäminen

Injektoikaa riippuvuus kutsulla .environment(\.fetchUser, container.fetchUser) ja lukekaa se näkymissä kutsulla @Environment(\.fetchUser).

ContentView()
  .environment(\.fetchUser, container.fetchUser)

// In a deep view:
@Environment(\.fetchUser) private var fetchUser

Rajatut säiliöt

Luokaa ominaisuuskohtaisia alisäiliöitä, jotka perivät jaetut riippuvuudet mutta omistavat ominaisuuskohtaiset riippuvuutensa.

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
  }
}

Composition Rootin testaaminen

Testatkaa säiliön tehdasmetodit varmistamalla, että palautetuilla olioilla on oikea tyyppi ja määritys.

func testContainerBuildsProfileView() {
  let container = AppContainer(db: InMemoryDatabase())
  let view = container.makeRootView()
  XCTAssertTrue(type(of: view) == ProfileView.self)
}

Ympyräriippuvuuksien välttäminen

Jos A riippuu B:stä ja B riippuu A:sta, tuokaa mukaan välittäjä tai järjestelkää vastuut uudelleen syklin katkaisemiseksi.

// Circular:
// UserService → NotificationService → UserService
// Fix: UserService → NotificationInput (protocol) ← NotificationService

Milloin DI-kehystä kannattaa käyttää

Manuaalinen kytkentä skaalautuu hyvin keskikokoisissa sovelluksissa. Harkitkaa kehyksiä (Needle, Swinject) vasta, kun säiliöstä tulee liian suuri ylläpidettäväksi.

// Manual: fine for <20 top-level dependencies
// Framework: helps with large teams, 50+ services, code-generation for factories

Kertauksen esimerkki

Pienen sovelluksen täydellisessä kytkentäesimerkissä säiliö rakentaa kaikki riippuvuudet ja tehdas tuottaa juurinäkymän.

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))
  }
}

Pikatarkistus

Mikä on Composition Root Swift-sovelluksessa?

Oppitunnin kertaus

Kytkekää sovellus Composition Rootissa (yleensä @main). Käyttäkää AppContainer-säiliötä ja lazy-ominaisuuksia oikean rakennusjärjestyksen varmistamiseksi. Lisätkää tehdasmetodeja näyttökohtaisten graafien luomiseen. Injektoikaa syvälle ulottuvat riippuvuudet mukautettujen EnvironmentKey-avainten avulla. Katkaiskaa ympyräriippuvuudet välittäjäprotokollilla.

Aloita maksutta

Opi Swift tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
122
Oppitunnit
409

Usein kysytyt kysymykset

Onko oppitunti ”Kerrosten yhdistäminen ilman DI-kehystä” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Swift Academy-oppimispolun 3 oppituntia, myös oppitunnin “Kerrosten yhdistäminen ilman DI-kehystä”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Kerrosten yhdistäminen ilman DI-kehystä”?

Olioiden koostaminen sovelluksen käynnistyskohdassa Composition Root -mallilla. Harjoittelet Swift Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Swift Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Swift Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Kerrosten yhdistäminen ilman DI-kehystä”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Swift Academy-oppitunnilla?

Kyllä. Jokainen Swift Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Kerroksittainen arkkitehtuuri: toimialue, data ja esityskerros
  2. Käyttötapaus- ja repository-mallit
  3. Riippuvuuksien kääntäminen protokolla-abstraktioilla
  4. Kerrosten yhdistäminen ilman DI-kehystä
← Takaisin: Swift Academy