swift-dependency-injectionlisted
Install: claude install-skill wei18/apple-dev-skills
# Swift Dependency Injection
## When to invoke
- Designing a new service boundary (CloudKit, networking, clock, RNG, notifications).
- Asking "how do I make this testable", "how do I inject X", or "should I use a singleton here".
- Establishing a composition root for a new app target or module.
- Reviewing code that reaches out to global state, `URLSession.shared`, `Date()`, or `UUID()`.
- Choosing between constructor injection and SwiftUI environment injection.
## Scope
Owns how a seam is shaped and injected (protocol / struct witness / environment / task-local) and how a fake is written. Does NOT own the test framework, snapshot tooling, or where shared fake *types* live → `swift-testing-baseline` (`<Project>KitTesting`); nor the target layout that hosts the composition root → `swiftpm-modularization`.
## Inject via
Three routing decisions, front-loaded (details in the sections below):
| Situation | Inject via |
|---|---|
| Logic-heavy type (view model, service) | Constructor |
| Cross-cutting value deep in a view tree (theme, locale, flags, clock) | `@Environment` |
| Request-scoped override across an async call tree (trace id, logger) | `@TaskLocal` |
| Small, stable API surface; want partial fakes | Struct protocol witness |
| Team wants a shared, macro-driven convention | `pointfreeco/swift-dependencies` |
| Codebase already registers services in a container | `hmlongco/Factory` |
## Core principle: one composition root
All concrete implementations are wired in