Set up dependency injection
✓Works with OpenClaudeYou are a software architect. The user wants to set up dependency injection in their application to decouple dependencies and improve testability.
What to check first
- Verify your project has a package manager initialized (
package.jsonfor Node.js,pom.xmlfor Java, etc.) - Identify all classes or modules that currently have hard dependencies on concrete implementations
- Determine whether you need a DI framework (tsyringe, inversify, Spring, Guice) or will implement manual injection
Steps
- Choose a DI container—for TypeScript/Node.js use
tsyringeorinversify; for Java use Spring Framework or Google Guice - Install the framework:
npm install tsyringe reflect-metadata(or equivalent for your ecosystem) - Import
reflect-metadataat your application entry point before any other code runs - Create an interface that defines your service contract (e.g.,
IUserRepository) - Implement concrete classes that satisfy the interface (e.g.,
UserRepository,MockUserRepository) - Register implementations in the container using decorators (
@injectable(),@inject()) or manual registration - Inject dependencies into constructors using the decorator pattern or container.get() calls
- Update your bootstrap/main file to resolve root services from the container instead of instantiating directly
Code
import 'reflect-metadata';
import { Container, injectable, inject } from 'tsyringe';
// Step 1: Define service interfaces
interface ILogger {
log(message: string): void;
}
interface IUserRepository {
getUserById(id: string): Promise<{ id: string; name: string }>;
}
// Step 2: Implement concrete classes with @injectable decorator
@injectable()
class ConsoleLogger implements ILogger {
log(message: string): void {
console.log(`[LOG] ${message}`);
}
}
@injectable()
class UserRepository implements IUserRepository {
async getUserById(id: string) {
return { id, name: 'John Doe' };
}
}
// Step 3: Inject dependencies into dependent classes
@injectable()
class UserService {
constructor(
@inject('ILogger') private logger: ILogger,
@inject('IUserRepository') private userRepository: IUserRepository
) {}
async getUser(id: string) {
this.logger.log(`Fetching user ${id}`);
return this.userRepository.getUserById(id);
}
}
// Step 4: Register implementations in container
const container = new Container();
container.register('ILogger', { useClass: ConsoleLogger });
container.register('IUserRepository', { useClass: UserRepository });
container.registerSingleton(UserService);
// Step 5: Resolve from container instead of instantiating directly
const userService = container.resolve(UserService);
// Step 6: Use the service
userService.getUser('123').
Note: this example was truncated in the source. See the GitHub repo for the latest full version.
Common Pitfalls
- Treating this skill as a one-shot solution — most workflows need iteration and verification
- Skipping the verification steps — you don't know it worked until you measure
- Applying this skill without understanding the underlying problem — read the related docs first
When NOT to Use This Skill
- When a simpler manual approach would take less than 10 minutes
- On critical production systems without testing in staging first
- When you don't have permission or authorization to make these changes
How to Verify It Worked
- Run the verification steps documented above
- Compare the output against your expected baseline
- Check logs for any warnings or errors — silent failures are the worst kind
Production Considerations
- Test in staging before deploying to production
- Have a rollback plan — every change should be reversible
- Monitor the affected systems for at least 24 hours after the change
Related Architecture Skills
Other Claude Code skills in the same category — free to download.
Singleton Pattern
Implement Singleton pattern
Factory Pattern
Implement Factory pattern
Observer Pattern
Implement Observer/PubSub pattern
Strategy Pattern
Implement Strategy pattern
Repository Pattern
Implement Repository pattern for data access
CQRS Setup
Implement CQRS pattern
Event Sourcing
Implement Event Sourcing pattern
Want a Architecture skill personalized to YOUR project?
This is a generic skill that works for everyone. Our AI can generate one tailored to your exact tech stack, naming conventions, folder structure, and coding patterns — with 3x more detail.