Skip to content
Agentmart
Submit a tool

swift-factory-di

MUST USE for questions about the Swift Factory dependency injection library by hmlongco, also called FactoryKit.

Skill by guillevc

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/guillevc-swift-factory-di

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

MUST USE for questions about the Swift Factory dependency injection library by hmlongco, also called FactoryKit. Covers Factory 2.x APIs, best practices, testing, and migration. Trigger on setting up containers or registrations, scopes (.singleton, .cached, .shared, .graph, .unique), property wrappers (@Injected, @LazyInjected, @WeakLazyInjected, @DynamicInjected, @InjectedObject, @InjectedObservable), flaky tests from container state, circular dependency errors, SwiftUI previews, migration from Factory 1.x to 2.x, ContainerTrait, contexts (.onTest, .onPreview, .onSimulator), imports of FactoryKit/Factory, Container.shared, SharedContainer, @Injected keypaths like \.serviceName, or any Factory-specific API. Do not use for Swinject, swift-dependencies, Dagger, the factory design pattern, or generic DI concepts.

Use cases: design, backend, testing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/swift-factory-di

What's inside

Skill name
swift-factory-di
Description
MUST USE for questions about the Swift Factory dependency injection library by hmlongco, also called FactoryKit. Covers Factory 2.x APIs, best practices, testing, and migration. Trigger on setting up containers or registrations, scopes (.singleton, .cached, .shared, .graph, .unique), property wrappers (@Injected, @LazyInjected, @WeakLazyInjected, @DynamicInjected, @InjectedObject, @InjectedObservable), flaky tests from container state, circular dependency errors, SwiftUI previews, migration from Factory 1.x to 2.x, ContainerTrait, contexts (.onTest, .onPreview, .onSimulator), imports of FactoryKit/Factory, Container.shared, SharedContainer, @Injected keypaths like \.serviceName, or any Factory-specific API. Do not use for Swinject, swift-dependencies, Dagger, the factory design pattern, or generic DI concepts.
License
MIT
Instructions
451 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Files (4)

  • SKILL.md
  • api-reference.md · references/
  • migration-guide.md · references/
  • testing-patterns.md · references/

SKILL.md (first lines)

# Factory DI — Reference & Optimization Guide

> Based on [Factory](https://github.com/hmlongco/Factory) **2.5.3** by [Michael Long (hmlongco)](https://github.com/hmlongco) — a compile-time safe, container-based dependency injection framework for Swift.
>
> This skill is an unofficial community resource. Factory is licensed under the MIT License.

Factory is under 1000 lines of executable code, yet provides containers, scopes, contexts, decorators, parameter injection, and full SwiftUI integration. It requires no code generation, build scripts, or runtime reflection.

As of 2.5.0, the recommended import is `import FactoryKit` (not `import Factory`) to avoid SPM naming conflicts.

---

## Core Patterns

### Defining a Factory

Factories are computed properties on container extensions. Each returns a `Factory<T>` that wraps a closure producing the dependency:

```swift
extension Container {
    var networkService: Factory<NetworkServiceType> {
        self { URLSessionNetworkService() }
    }
}
```

The `self { ... }` syntax is shorthand for `Factory(self) { ... }`. The closure is `@Sendable`.

### Resolving Dependencies

```swift
// Direct resolution
let service = Container.shared.networkService()

// Property wrapper (uses Container.shared implicitly)
@Injected(\.networkService) var service

// From a custom container
@Injected(\MyContainer.networkService) var service
```

### Constructor Injection (Preferred)

Wire dependencies through the container itself — this keeps the dependency graph visible:

```swift
extension Container {
    var repository: Factory<UserRepository> {
        self { UserRepository(network: self.networkService()) }
    }
}
```

### Protocol-Based Registration

Always register against protocols for testability:

```swift
var networkService: Factory<NetworkServiceType> {  // protocol, not concrete
    self { URLSessionNetworkService() }
}
```

### Custom Containers

For modular apps, define separate containers per feature or module:

```swift
final class AuthContainer: SharedContainer {
    static let shared = AuthContainer()
    let manager = ContainerManager()

    var authService: Factory<AuthServiceType> {
        self { KeychainAuthService() }
    }
}
```

---

## Property Wrapper Selection Guide

Choosing the right wrapper matters for performance, correctness, and lifecycle:

| Wrapper | Resolves | Re-resolves | Holds | Use when |
|---------|----------|-------------|-------|----------|
| `@Injected` | At init | Never | Strong | Default choice. Dependency is needed immediately and won't change. |
| `@LazyInjected` | First access | Never | Strong | Resolution is expensive or has side effects; delay until actually needed. |
| `@WeakLazyInjected` | First access | If released | Weak | Breaking retain cycles or shared-scope dependencies you don't want to own. |
| `@DynamicInjected` | Every access | Every access | None | Dependency may change at runtime (e.g., after re-registration). Rare. |
| `@InjectedObject` | At init | Never | Strong (StateObject) | SwiftUI views needing an `ObservableObject` view model. Owns the instance. |
| `@InjectedObservable` | At init | Never | Strong (State) | SwiftUI views with iOS 17+ `@Observable` types. |

**Rules of thumb:**
- Start with `@Injected` unless you have a reason not to.
- In SwiftUI views, use `@InjectedObject` (pre-iOS 17) or `@InjectedObservable` (iOS 17+) instead of manually wrapping in `@StateObject`/`@State`.
- `@DynamicInjected` has a resolution cost on every property access — only use it when the registration genuinely changes at runtime.

### LazyInjected Extras

`@LazyInjected` exposes helpers through its projected value (`$`):

```swift
@LazyInjected(\.heavyService) var service

// Check if resolved yet
if let resolved = $service.resolvedOrNil() { ... }

// Force resolution
$service.resolve()
```

---

## Scope Selection Guide

Scopes control how long a resolved instance lives. The default is `.unique` (new instance every time).

```

From guillevc/skills, MIT.

More from guillevc/skills

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Jun 28, 2026 (4 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from guillevc

Cite this page

swift-factory-di skill. Agent Mart. https://agentmart.dev/skills/guillevc-swift-factory-di (last updated 2026-10-24)