Why Dependency Injection?
Dependency injection provides several benefits:- Testability: Easily mock dependencies in unit tests
- Loose Coupling: Controllers don’t directly instantiate their dependencies
- Lifecycle Management: Control how and when dependencies are created
- Configuration: Centralize dependency configuration
Supported Containers
tsoa supports several popular IoC containers:- InversifyJS - Powerful IoC container with decorator support
- TypeDI - Lightweight dependency injection for TypeScript
- tsyringe - Microsoft’s lightweight DI container
- Custom - Implement your own container interface
InversifyJS Setup
Create Services
Create injectable services:
src/services/databaseService.ts
src/services/userService.ts
TypeDI Setup
tsyringe Setup
Dynamic Container
Create a container per request for request-scoped dependencies:src/ioc.ts
tsoa.json
Lifecycle Scopes
Singleton
One instance for the entire application:Transient
New instance every time:Request
One instance per HTTP request:Testing with DI
Dependency injection makes testing much easier:src/controllers/userController.spec.ts
Advanced Patterns
Factory Pattern
Circular Dependencies
Avoid circular dependencies, but if needed:Conditional Binding
Multi-tenancy
Support multiple tenants with scoped containers:src/ioc.ts
Configuration
Inject configuration:src/config.ts
Best Practices
Use Interfaces
Use Interfaces
Bind to interfaces rather than concrete implementations for better flexibility:
Avoid Service Locator
Avoid Service Locator
Don’t use the container directly in your business logic. Inject dependencies through constructors.
Choose Appropriate Scopes
Choose Appropriate Scopes
Use singletons for stateless services, transient for lightweight objects, and request scope for request-specific data.
Keep Constructors Simple
Keep Constructors Simple
Don’t do complex work in constructors. Use initialization methods if needed.
Troubleshooting
”Cannot resolve” Errors
Ensure all dependencies are registered:Circular Dependencies
Refactor to remove circular dependencies or use lazy injection.Missing Decorators
EnsureexperimentalDecorators and emitDecoratorMetadata are enabled in tsconfig.json.
Next Steps
Testing
Learn how to test your controllers
Authentication
Implement authentication with DI