Service Container Overview
The ServiceContainer is the dependency injection container of ECS Framework, responsible for managing the registration, resolution, and lifecycle of all services.
What is a Service Container
Section titled “What is a Service Container”The service container is a lightweight dependency injection (DI) container that provides:
- Service Registration: Register service types into the container
- Service Resolution: Retrieve service instances from the container
- Lifecycle Management: Automatically manage service instance creation and destruction
- Dependency Injection: Automatically resolve dependencies between services
Core Concepts
Section titled “Core Concepts”Service
Section titled “Service”A service is a class that implements the IService interface and must provide a dispose() method for resource cleanup:
import { IService } from '@esengine/ecs-framework';
class MyService implements IService { constructor() { // Initialization logic }
dispose(): void { // Cleanup resources }}Service Identifier
Section titled “Service Identifier”Service identifiers are used to uniquely identify a service in the container. Two types are supported:
- Class Constructor: Use the service class directly as identifier
- Symbol: Use Symbol as identifier (recommended for interface abstractions)
// Method 1: Using class as identifierCore.services.registerSingleton(DataService);const data = Core.services.resolve(DataService);
// Method 2: Using Symbol as identifierconst IFileSystem = Symbol.for('IFileSystem');Core.services.registerInstance(IFileSystem, new TauriFileSystem());const fs = Core.services.resolve<IFileSystem>(IFileSystem);Lifecycle
Section titled “Lifecycle”- Singleton: Only one instance throughout the application lifecycle
- Transient: Creates a new instance on each resolution
Container Hierarchy
Section titled “Container Hierarchy”ECS Framework provides three levels of service containers:
Core.services (Application global) └─ World.services (World level) └─ Scene.services (Scene level)// Core levelconst container = Core.services;
// World levelconst worldContainer = world.services;
// Scene levelconst sceneContainer = scene.services;Basic Usage
Section titled “Basic Usage”Registering Services
Section titled “Registering Services”// Singleton serviceCore.services.registerSingleton(DataService);
// Transient serviceCore.services.registerTransient(CommandService);
// Register instanceCore.services.registerInstance(ConfigService, config);
// Factory functionCore.services.registerSingleton(LoggerService, (container) => { const logger = new LoggerService(); logger.setLevel('debug'); return logger;});Resolving Services
Section titled “Resolving Services”// Resolve service (throws if not registered)const dataService = Core.services.resolve(DataService);
// Try resolve (returns null if not registered)const optional = Core.services.tryResolve(OptionalService);
// Check if registeredif (Core.services.isRegistered(DataService)) { // ...}Next Steps
Section titled “Next Steps”- Built-in Services - Framework provided services
- Dependency Injection - Decorators and auto-injection
- PluginServiceRegistry - Plugin service registry
- Advanced Usage - Symbol patterns, best practices