factory-dependency-injection

Implements container-based dependency injection in Swift and SwiftUI using FactoryKit.

2.9k|191|Updated Jun 1, 2022
One-click install
npx skills add https://github.com/hmlongco/Factory --skill factory-dependency-injection
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: factory-dependency-injection
Source: https://github.com/hmlongco/Factory/tree/main/.claude/skills/factory-dependency-injection
Command: npx skills add https://github.com/hmlongco/Factory --skill factory-dependency-injection

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Wiring dependencies in Swift apps often means choosing between verbose runtime registration frameworks or fragile service locators. This Skill provides authoritative guidance for Factory, a compile-time-safe, container-based DI system, so registrations, resolutions, scopes, and test overrides are written correctly the first time.

Core Features & Use Cases

  • Registrations and Resolution: Define factories as computed properties on Container, resolve via call sites, property wrappers (@Injected, @LazyInjected, @InjectedObject, @InjectedObservable), or the global dependency function.
  • Scopes, Contexts, and Modifiers: Control lifetimes with .unique, .cached, .shared, .singleton, .graph, and custom scopes; override registrations per environment with .onTest, .onPreview, .onArg, and .onDebug.
  • Testing and Cross-Module Wiring: Isolate parallel Swift Testing suites with the .container trait from FactoryTesting, and wire protocol implementations across modules using promised() and AutoRegistering.
  • Use Case: When a SwiftUI view model needs a mockable network service, register it on Container with a .singleton scope, inject it with @Injected, and override it in tests with Container.shared.myService.register { MockService() }.

Quick Start

Show me how to register a network service on Container and inject it into a SwiftUI view model using FactoryKit.

Frequently Asked Questions about factory-dependency-injection

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I register a dependency with Factory in Swift?

Add a computed property returning Factory<T> to an extension of Container, using the closure sugar self { MyService() }. Resolution is Container.shared.myService() or the @Injected(\.myService) property wrapper, and missing registrations fail at compile time.

Factory vs Resolver vs Swinject for Swift dependency injection?

Factory is compile-time safe because each registration is a typed computed property, so missing registrations fail to compile rather than failing at runtime. It needs no upfront registration of every type, no codegen, and supports scopes, contexts, and Swift Testing traits out of the box.

Should I import Factory or FactoryKit in my Swift package?

Import FactoryKit in app and library code; the module is named FactoryKit so it does not collide with the Factory type. In test targets add only FactoryTesting, which transitively exposes FactoryKit, since adding FactoryKit directly to the test target creates duplicate factories.

How do I mock Factory dependencies in Swift Testing?

Annotate the suite or test with the .container trait from FactoryTesting, then call Container.shared.myService.register { MockService() } inside the test. Each test gets a fresh TaskLocal container and a cloned singleton scope, so parallel tests stay isolated.

Why is my Factory onTest override not taking effect?

Modifiers baked into the factory definition are re-applied on every read of the computed property, so the innermost definition wins over call-site overrides. Move the override into autoRegister(), chain it at the resolve site, or add .once() after the baked-in modifier.

Does Factory support constructor parameters for injected services?

Yes, use ParameterFactory<P, T> and resolve with Container.shared.paramService(42) or dependency(\.paramService, parameter: 42). The @Injected property wrapper cannot pass parameters, and per-parameter caching requires .scopeOnParameters with a Hashable parameter.