Skip to content

@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