Dependency Injection Guide
Overview
NitroStack uses a dependency injection (DI) container for managing class dependencies, making your code testable and modular.
@Injectable Decorator
Mark classes for injection:
import { Injectable } from 'nitrostack';
@Injectable()
export class UserService {
async findById(id: string) {
return { id, name: 'John Doe' };
}
}
Constructor Injection
Inject dependencies via constructor:
export class UserTools {
constructor(
private userService: UserService,
private emailService: EmailService,
private db: DatabaseService
) {}
@Tool({ name: 'create_user' })
async createUser(input: any) {
const user = await this.userService.create(input);
await this.emailService.sendWelcome(user.email);
return user;
}
}
Service Lifecycle
Services are singletons by default - one instance for the entire application.
Circular Dependencies
Avoid circular dependencies in constructors. If needed, use @Inject() with forward references.
Best Practices
- Inject services, not classes - Keep logic in services
- Use interfaces - Program to abstractions
- Avoid new keyword - Let DI container create instances
- Test with mocks - Easier with DI