AgentSkillsCN

dependency-wirer

更新DependencyContainer.swift,以适配新的仓库、用例与ViewModel。遵循VitalArc的依赖注入模式。

SKILL.md
--- frontmatter
name: dependency-wirer
description: Update DependencyContainer.swift to wire new repositories, use cases, and ViewModels. Follows VitalArc's dependency injection patterns.
context: fork
agent: Plan
allowed-tools: Read, Edit, Grep, Glob, TaskCreate, TaskUpdate, TaskList
argument-hint: <feature-name> [--entity=Name] [--repository=Name] [--usecase=Name]

Dependency Wirer

Wires new components into VitalArc's dependency injection system.

Execution: Runs in forked context with Plan agent for isolated analysis and targeted edits.

What It Does

  1. Adds repository implementations to DependencyContainer
  2. Adds use case initializations
  3. Updates environment injection
  4. Creates SwiftData @Model if needed

VitalArc DI Pattern

swift
// DependencyContainer.swift structure
@MainActor
final class DependencyContainer: ObservableObject {
    // Repositories
    let workoutRepository: WorkoutRepository
    let nutritionRepository: NutritionRepository
    // ... add new repositories here

    // Use Cases
    let createWorkoutUseCase: CreateWorkoutUseCase
    let getWorkoutsUseCase: GetWorkoutsUseCase
    // ... add new use cases here

    init(modelContext: ModelContext) {
        // Initialize repositories
        self.workoutRepository = SwiftDataWorkoutRepository(modelContext: modelContext)

        // Initialize use cases
        self.createWorkoutUseCase = CreateWorkoutUseCase(repository: workoutRepository)
    }
}

Task Tracking

When wiring multiple components, create tasks to track progress:

javascript
// Create task for each component being wired
components.forEach(component => {
  TaskCreate({
    subject: `Wire ${component.type}: ${component.name}`,
    description: `Add ${component.name} to DependencyContainer:
      - Add property declaration
      - Add initialization in init()
      - Verify dependencies are available`,
    activeForm: `Wiring ${component.name}`
  })
})

// Update task status as each component is wired
TaskUpdate({
  taskId: task.id,
  status: "completed"
})

This provides visibility when wiring complex features with multiple components.

Implementation

1. Read Current Container

bash
# Get current DependencyContainer structure
cat VitalArc/Infrastructure/DependencyContainer.swift

2. Identify Injection Points

Find where to add:

  • Repository property declaration
  • Repository initialization
  • Use case property declaration
  • Use case initialization

3. Generate Wiring Code

For a new feature like "Achievements":

swift
// Add to properties section
let achievementRepository: AchievementRepository
let getAchievementsUseCase: GetAchievementsUseCase
let unlockAchievementUseCase: UnlockAchievementUseCase

// Add to init
self.achievementRepository = SwiftDataAchievementRepository(modelContext: modelContext)
self.getAchievementsUseCase = GetAchievementsUseCase(repository: achievementRepository)
self.unlockAchievementUseCase = UnlockAchievementUseCase(repository: achievementRepository)

4. Apply Edits

Use Edit tool to insert at correct locations:

code
Edit file: VitalArc/Infrastructure/DependencyContainer.swift
old_string: let nutritionRepository: NutritionRepository
new_string: let nutritionRepository: NutritionRepository
    let achievementRepository: AchievementRepository

Input Parameters

ParameterDescriptionExample
feature-nameFeature being wiredachievements
--entityEntity name (optional)Achievement
--repositoryRepository protocol nameAchievementRepository
--usecaseUse case names (comma-separated)GetAchievements,UnlockAchievement

Output Format

Wiring Plan

markdown
## Dependency Wiring Plan: Achievements

### Components to Wire

| Type | Name | Dependencies |
|------|------|--------------|
| Repository | AchievementRepository | ModelContext |
| Use Case | GetAchievementsUseCase | AchievementRepository |
| Use Case | UnlockAchievementUseCase | AchievementRepository |

### Files to Modify

1. **DependencyContainer.swift**
   - Add repository property
   - Add use case properties
   - Add initializations

2. **Create SwiftData Model** (if needed)
   - AchievementModel.swift with @Model

### Generated Code

#### Repository Property
```swift
let achievementRepository: AchievementRepository

Use Case Properties

swift
let getAchievementsUseCase: GetAchievementsUseCase
let unlockAchievementUseCase: UnlockAchievementUseCase

Initialization

swift
self.achievementRepository = SwiftDataAchievementRepository(modelContext: modelContext)
self.getAchievementsUseCase = GetAchievementsUseCase(repository: achievementRepository)
self.unlockAchievementUseCase = UnlockAchievementUseCase(repository: achievementRepository)

Apply Changes?

Confirm to apply these edits to DependencyContainer.swift

code

### After Wiring

```markdown
## Dependency Wiring Complete

### Changes Applied

| File | Change |
|------|--------|
| DependencyContainer.swift | +3 properties, +3 initializations |

### Verification
- [ ] Build passes
- [ ] Repository accessible via container
- [ ] Use cases can be injected into ViewModels

### Next Steps
1. Create SwiftDataAchievementRepository implementation
2. Create ViewModel with use case injection
3. Add @Environment access in views

SwiftData Model Generation

If entity needs persistence, generate @Model:

swift
// AchievementModel.swift
import SwiftData

@Model
final class AchievementModel {
    @Attribute(.unique) var id: UUID
    var name: String
    var achievementDescription: String
    var unlockedAt: Date?
    var category: String

    init(id: UUID = UUID(), name: String, description: String, unlockedAt: Date? = nil, category: String) {
        self.id = id
        self.name = name
        self.achievementDescription = description
        self.unlockedAt = unlockedAt
        self.category = category
    }

    // Domain conversion
    func toDomain() -> Achievement {
        Achievement(
            id: id,
            name: name,
            description: achievementDescription,
            unlockedAt: unlockedAt,
            category: AchievementCategory(rawValue: category) ?? .milestone
        )
    }

    static func fromDomain(_ achievement: Achievement) -> AchievementModel {
        AchievementModel(
            id: achievement.id,
            name: achievement.name,
            description: achievement.description,
            unlockedAt: achievement.unlockedAt,
            category: achievement.category.rawValue
        )
    }
}

Error Handling

Container Not Found

markdown
## ❌ DependencyContainer Not Found

Could not find DependencyContainer.swift at expected location.

Expected: VitalArc/Infrastructure/DependencyContainer.swift

Please verify project structure.

Duplicate Component

markdown
## ⚠️ Component Already Exists

AchievementRepository is already declared in DependencyContainer.

**Existing declaration** (line 45):
```swift
let achievementRepository: AchievementRepository

Skip this component or choose a different name.

code

### Missing Dependencies

```markdown
## ⚠️ Missing Dependencies

The following dependencies are required but not found:

- `AchievementRepository` protocol (not in Domain/Repositories/)
- `SwiftDataAchievementRepository` class (not in Data/)

Create these files first, then re-run dependency-wirer.