0.1.1 • Published 6 months ago
@nexus-dev/core v0.1.1
Nexus React Framework - Core
Dependency Injection (DI) Container
The Nexus React Framework provides a powerful dependency injection container that helps manage dependencies and promote loose coupling in your application.
Table of Contents
Overview
The DI container is responsible for:
- Managing the lifecycle of services and components
- Resolving dependencies automatically
- Supporting different scopes (Singleton, Transient, Request)
- Enabling property and constructor injection
- Supporting circular dependencies
Basic Usage
1. Define Injectable Services
import { Injectable } from '@nexus/core';
@Injectable()
export class UserService {
getUsers() {
return ['Alice', 'Bob', 'Charlie'];
}
}2. Register Services
import { Container } from '@nexus/core/di';
import { UserService } from './user.service';
// Register a service
Container.getInstance().register(UserService, { useClass: UserService });
// Or use the shorthand
Container.getInstance().register(UserService, UserService);3. Resolve Dependencies
// Get an instance of UserService
const userService = Container.getInstance().resolve(UserService);
const users = userService.getUsers();Decorators
@Injectable
Marks a class as available to the DI container for injection.
@Injectable({
scope: 'SINGLETON', // or 'TRANSIENT', 'REQUEST'
eager: false, // if true, instantiated when registered
provide: MyService, // optional token to provide
deps: [OtherService] // explicit dependencies
})
export class MyService {}@Inject
Specifies which token should be injected for a parameter or property.
class MyService {
constructor(
@Inject('CONFIG') private config: any,
@Inject(OtherService) private otherService: OtherService
) {}
}@Optional
Marks a dependency as optional. The container will inject undefined if the dependency is not found.
class MyService {
constructor(
@Optional() private logger?: Logger
) {}
}Scopes
The container supports three scopes:
- Singleton (default): A single instance is created and shared
- Transient: A new instance is created each time
- Request: A new instance is created for each request context
Provider Types
1. Class Provider
{
provide: MyService,
useClass: MyServiceImpl,
scope: 'SINGLETON',
deps: [OtherService]
}2. Value Provider
{
provide: 'API_KEY',
useValue: '12345-abcde'
}3. Factory Provider
{
provide: 'CONFIG',
useFactory: (http) => fetchConfig(http),
deps: [HttpService]
}API Reference
Container
getInstance(): Get the singleton container instanceregister<T>(token: Token<T>, provider: Provider<T> | Constructor<T>): Register a providerresolve<T>(token: Token<T>): T: Resolve a dependency (throws if not found)tryResolve<T>(token: Token<T>): T | undefined: Try to resolve a dependencyhas(token: Token<any>): boolean: Check if a token is registeredstartRequestContext(requestId?: string): void: Start a new request contextendRequestContext(requestId?: string): void: End a request context
Best Practices
- Prefer constructor injection over property injection for required dependencies
- Use interfaces for better testability and loose coupling
- Keep constructors simple - they should only assign dependencies to properties
- Avoid service location - prefer dependency injection over
Container.getInstance().resolve() - Use request scope for request-specific data
- Be careful with circular dependencies - they can be resolved but may indicate design issues
- Use @Optional() for truly optional dependencies
Example
import { Injectable, Inject, Optional } from '@nexus/core';
import { Container } from '@nexus/core/di';
// Service with dependencies
@Injectable()
class Logger {
log(message: string) {
console.log(`[${new Date().toISOString()}] ${message}`);
}
}
@Injectable()
class UserService {
constructor(
@Optional() private logger?: Logger
) {}
getUsers() {
this.logger?.log('Fetching users');
return ['Alice', 'Bob'];
}
}
// Register services
const container = Container.getInstance();
container.register(Logger, Logger);
container.register(UserService, UserService);
// Resolve and use
const userService = container.resolve(UserService);
console.log(userService.getUsers());License
MIT