Quick Start
This guide will walk you through the basic concepts of the DI framework with simple examples.
1. Basic Service
The simplest way to use the framework is to mark a class with the @Container() decorator:
import { Container } from 'di-framework/decorators';
@Container()
export class DatabaseService {
connect(): void {
console.log('Connected to database');
}
query(sql: string) {
console.log('Executing query:', sql);
return { rows: [] };
}
}
The @Container() decorator automatically registers the service with the DI container.
2. Service with Dependencies
You can inject dependencies into your services using the @Component() decorator:
Property Injection
import { Container, Component } from 'di-framework/decorators';
import { DatabaseService } from './DatabaseService';
@Container()
export class UserService {
@Component(DatabaseService)
private db!: DatabaseService;
constructor() {}
getUser(id: string) {
return this.db.query(`SELECT * FROM users WHERE id = '${id}'`);
}
}
Constructor Injection
@Container()
export class UserService {
constructor(
@Component(DatabaseService) private db: DatabaseService
) {}
getUser(id: string) {
return this.db.query(`SELECT * FROM users WHERE id = '${id}'`);
}
}
3. Resolving Services
To use your services, resolve them from the container:
import { useContainer } from 'di-framework/container';
import { UserService } from './UserService';
const container = useContainer();
const userService = container.resolve<UserService>(UserService);
// All dependencies are automatically injected!
const user = userService.getUser('123');
4. Multiple Dependencies
You can inject multiple dependencies into a single service:
@Container()
export class ApplicationContext {
constructor(
@Component(DatabaseService) private db: DatabaseService,
@Component(LoggerService) private logger: LoggerService,
@Component(AuthService) private auth: AuthService
) {}
async initialize() {
this.logger.log('Initializing application...');
await this.db.connect();
this.auth.setup();
}
}
5. How It Works
When you call container.resolve(ServiceClass):
The container creates a new instance (or returns existing singleton)
It examines the constructor parameters and their types
It recursively resolves each dependency
Dependencies are injected into the constructor or properties
The configured instance is returned
By default, all services are singletons - the same instance is reused across your application.
Complete Example
Here's a complete example showing how everything works together:
// DatabaseService.ts
import { Container } from 'di-framework/decorators';
@Container()
export class DatabaseService {
connect() {
console.log('Database connected');
}
query(sql: string) {
return { rows: [] };
}
}
// UserService.ts
import { Container, Component } from 'di-framework/decorators';
import { DatabaseService } from './DatabaseService';
@Container()
export class UserService {
@Component(DatabaseService)
private db!: DatabaseService;
getUser(id: string) {
return this.db.query(`SELECT * FROM users WHERE id = '${id}'`);
}
}
// main.ts
import { useContainer } from 'di-framework/container';
import { UserService } from './UserService';
const container = useContainer();
const userService = container.resolve(UserService);
const user = userService.getUser('123');
console.log(user);
Last modified: 10 November 2025