Appearance
@xinjectable - Service Definition Decorator
The @xinjectable decorator used to define services in XCon Widget Framework.
🎯 What is it?
The @xinjectable decorator marks a class as a service. During bootstrap, these services are automatically registered to the DI system.
📦 Import
typescript
import { xinjectable } from '@xcons/widget';🔧 Basic Usage
typescript
@xinjectable()
export class DataService {
private data: any[] = [];
getData() {
return this.data;
}
addData(item: any) {
this.data.push(item);
}
}⚙️ Scope Definition
Determines the lifecycle scope of the service:
typescript
// Singleton (default) - Single instance
@xinjectable({ scope: 'singleton' })
export class ConfigService {}
// Transient - New for each use
@xinjectable({ scope: 'transient' })
export class LoggerService {}
// Scoped - Scope based
@xinjectable({ scope: 'scoped' })
export class RequestService {}🎪 Usage with Token
Assigning a custom token to the service:
typescript
import { createServiceToken } from '@xcons/widget';
const API_SERVICE = createServiceToken<ApiService>('API_SERVICE');
@xinjectable({ token: API_SERVICE })
export class ApiService {
// Implementation
}🔄 Lifecycle Hooks
typescript
import { xinjectable, OnServiceInit, OnServiceDestroy } from '@xcons/widget';
@xinjectable()
export class DatabaseService implements OnServiceInit, OnServiceDestroy {
async onServiceInit(): Promise<void> {
console.log('Service is starting...');
}
async onServiceDestroy(): Promise<void> {
console.log('Service is shutting down...');
}
}💉 Service Usage
typescript
import { xinject } from '@xcons/widget';
export class UserComponent {
@xinject(DataService)
private dataService!: DataService;
loadData() {
return this.dataService.getData();
}
}🔧 Manual Registration
typescript
import { registerService, registerValue } from '@xcons/widget';
// Service registration
registerService(DataService, { scope: 'singleton' });
// Value registration
registerValue('API_URL', 'https://api.example.com');🧪 Testing
typescript
import { ServiceRegistry } from '@xcons/widget';
// Mock service
class MockDataService {
getData() {
return ['mock-data'];
}
}
// Test setup
beforeEach(() => {
ServiceRegistry.getInstance().clear();
registerService(MockDataService, { token: DataService });
});📋 Best Practices
Use Token with Interface
typescript
export interface INotificationService {
notify(message: string): void;
}
const NOTIFICATION_TOKEN = createServiceToken<INotificationService>('NOTIFICATION');
@xinjectable({ token: NOTIFICATION_TOKEN })
export class ToastService implements INotificationService {
notify(message: string) {
console.log(message);
}
}Use Lifecycle Hooks
typescript
@xinjectable()
export class CacheService implements OnServiceInit, OnServiceDestroy {
async onServiceInit() {
await this.loadCache();
}
async onServiceDestroy() {
await this.saveCache();
}
}✨ Summary
With @xinjectable:
- ✅ Define services easily
- ✅ Use different scopes
- ✅ Type-safe injection with token system
- ✅ Resource management with lifecycle hooks
- ✅ Testable code