mcp-quiz-server
Version:
🧠AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.
120 lines (119 loc) • 3.73 kB
JavaScript
;
/**
* @fileoverview Simple Dependency Injection Container
* @version 1.0.0
* @since 2025-07-29
* @lastUpdated 2025-07-29
* @module DIContainer
* @description Lightweight dependency injection container for Clean Architecture.
* Manages service registration, resolution, and lifetime management.
* @requirementsTraceability {@link Requirements.REQ_ROUTES_004} - DI Container Integration with Graceful Fallback
* @requirementsTraceability {@link Requirements.REQ_ARCH_002} - Clean Architecture Patterns
* @testType unit
*
* @architecture
* Layer: Infrastructure (Dependency Injection)
* Pattern: Service Locator + Factory Pattern
* Lifecycle: Application-scoped singleton
*
* @relationships
* DEPENDS_ON:
* - None (core infrastructure component)
* USED_BY:
* - ServiceRegistry (Infrastructure)
* - All application services requiring DI
* - MCP tools and handlers
* MANAGES:
* - Service lifetimes (transient, singleton)
* - Service factory functions
* - Circular dependency detection
*
* @dataFlow
* register() → stores ServiceDescriptor → resolve() → factory() → instance
* Singleton: resolve() → check cache → return cached OR create new → cache → return
* Transient: resolve() → factory() → return new instance
*
* @responsibilities
* - Register services with factory functions and lifetimes
* - Resolve service dependencies at runtime
* - Manage singleton instance caching
* - Provide type-safe service resolution
* - Handle service registration validation
*
* @patterns
* - Service Locator: Central service registry
* - Factory Pattern: Service creation via factory functions
* - Singleton: Lifetime management for single instances
*
* @contributors Claude Code Agent
* @requirements REQ-ARCH-001 (Clean Architecture DI)
* @testCoverage Unit tests for registration, resolution, and lifecycle management
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DIContainer = void 0;
class DIContainer {
constructor() {
this.services = new Map();
}
/**
* Register a service
*/
register(token, factory, lifetime = 'transient') {
this.services.set(token, { factory, lifetime });
}
/**
* Register a singleton service
*/
registerSingleton(token, factory) {
this.register(token, factory, 'singleton');
}
/**
* Register an instance as singleton
*/
registerInstance(token, instance) {
this.services.set(token, {
factory: () => instance,
lifetime: 'singleton',
instance,
});
}
/**
* Resolve a service
*/
resolve(token) {
const descriptor = this.services.get(token);
if (!descriptor) {
throw new Error(`Service '${token}' not registered`);
}
// Return cached instance for singletons
if (descriptor.lifetime === 'singleton' && descriptor.instance) {
return descriptor.instance;
}
// Create new instance
const instance = descriptor.factory(this);
// Cache singleton instances
if (descriptor.lifetime === 'singleton') {
descriptor.instance = instance;
}
return instance;
}
/**
* Check if service is registered
*/
has(token) {
return this.services.has(token);
}
/**
* Clear all registrations
*/
clear() {
this.services.clear();
}
/**
* Get all registered service tokens
*/
getRegisteredServices() {
return Array.from(this.services.keys());
}
}
exports.DIContainer = DIContainer;