home / skills / willsigmon / sigstack / dependency-injection-setup
This skill helps you set up dependency injection in a TypeScript project by creating protocols, implementations, and DI container registrations.
npx playbooks add skill willsigmon/sigstack --skill dependency-injection-setupReview the files below or copy the command above to add this skill to your agents.
---
name: Dependency Injection Setup
description: Add new services to DIContainer, create protocol-based implementations, set up singletons or factories for Leavn app dependency injection
allowed-tools: Read, Edit, Grep
---
# Dependency Injection Setup
## Instructions
Add new services to Leavn's DIContainer:
1. **Create service protocol**:
```swift
// Services/MyDomain/MyServiceProtocol.swift
public protocol MyServiceProtocol {
func doSomething() async throws -> Result
}
```
2. **Create implementation**:
```swift
// Services/MyDomain/MyServiceLive.swift
public final class MyServiceLive: MyServiceProtocol {
public init() { }
public func doSomething() async throws -> Result {
// Implementation
}
}
```
3. **Register in DIContainer**:
```swift
// For singletons (stateful services):
private lazy var _myService = MyServiceLive()
var myService: MyServiceProtocol {
_myService
}
// For factories (stateless services):
var myService: MyServiceProtocol {
MyServiceLive()
}
```
4. **Use in ViewModels**:
```swift
let service = DIContainer.shared.myService
```
Use this skill when: Creating new service, adding dependency, setting up DI, refactoring to protocol-oriented design
This skill describes how to add new services to the Leavn DIContainer using protocol-based design and register either singletons or factory instances. It shows how to create a service protocol, implement a concrete class, register it with the container, and consume it from view models. The goal is predictable, testable dependency wiring for the app.
Define a service protocol that exposes the API your feature needs. Provide one or more concrete implementations (live, mock, or test doubles). Register the implementation in the DIContainer either as a singleton for stateful services or as a factory for stateless services. Consume the registered service via DIContainer.shared from view models or other consumers.
When should I prefer singleton over factory?
Choose singleton for services that represent shared application state or manage shared resources. Use factory for inexpensive, stateless objects that should be independent per consumer.
How do I swap implementations in tests?
Implement a mock/stub that conforms to the protocol and register it in the DIContainer for test runs, or provide a test-only DIContainer instance configured with test doubles.