0Pricing
Swift Academy · Lección

Integración de capas sin un framework de DI

Componga objetos en el punto de entrada de la app mediante el patrón Composition Root.

Integración de capas sin un framework de DI es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

Composition Root

El Composition Root es el único lugar donde se crean y conectan todos los objetos. En una aplicación de SwiftUI, normalmente es @main.

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

Patrón AppContainer

Una estructura o clase AppContainer construye el grafo de objetos y oculta la complejidad de la configuración a la estructura 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) }
}

Propiedades lazy para controlar el orden

Use propiedades lazy para asegurarse de que las dependencias se construyan en el orden correcto sin tener que establecerlo 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)
}

Métodos de fábrica

Añada métodos de fábrica al contenedor para crear objetos del nivel de vista con dependencias específicas de cada pantalla.

extension AppContainer {
  func makeOrderFlow() -> OrderFlowView {
    let repo = RemoteOrderRepository(api: api)
    let useCase = PlaceOrderUseCase(repo: repo)
    let vm = OrderViewModel(useCase: useCase)
    return OrderFlowView(viewModel: vm)
  }
}

Valores de entorno para la inyección

En SwiftUI, use EnvironmentKeys personalizados para inyectar dependencias en cualquier nivel del árbol de vistas sin tener que pasarlas por todas las vistas intermedias.

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

Uso de la clave de entorno

Inyecte mediante .environment(\.fetchUser, container.fetchUser) y lea el valor con @Environment(\.fetchUser) en las vistas.

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

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

Contenedores con ámbito

Cree contenedores secundarios para los ámbitos de las funcionalidades, de modo que hereden las dependencias compartidas y sean propietarios de las específicas de cada funcionalidad.

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

Pruebas del Composition Root

Pruebe los métodos de fábrica del contenedor verificando que los objetos devueltos tengan el tipo y la configuración correctos.

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

Cómo evitar dependencias circulares

Si A depende de B y B depende de A, introduzca un mediador o reorganice las responsabilidades para romper el ciclo.

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

Cuándo recurrir a un framework de DI

La configuración manual funciona bien en aplicaciones de tamaño mediano. Considere frameworks como Needle o Swinject únicamente cuando el contenedor sea demasiado grande para mantenerlo.

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

Ejemplo de repaso

Ejemplo completo de configuración en una aplicación pequeña: el contenedor construye todas las dependencias y una fábrica produce la vista raíz.

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

Comprobación rápida

¿Qué es el Composition Root en una aplicación de Swift?

Resumen de la lección

Configure la aplicación en un Composition Root (normalmente @main). Use un AppContainer con propiedades lazy para mantener el orden correcto de construcción. Añada métodos de fábrica para los grafos específicos de cada pantalla. Inyecte dependencias profundas mediante EnvironmentKeys personalizados. Rompa las dependencias circulares con protocolos mediadores.

Preguntas frecuentes

¿La lección «Integración de capas sin un framework de DI» es gratis?

Sí — el texto completo de «Integración de capas sin un framework de DI» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Integración de capas sin un framework de DI»?

Componga objetos en el punto de entrada de la app mediante el patrón Composition Root. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Integración de capas sin un framework de DI»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Capas: dominio, datos y presentación
  2. Patrones de casos de uso y repositorios
  3. Inversión de dependencias con abstracciones de protocolos
  4. Integración de capas sin un framework de DI
← Volver a Swift Academy