register method

Future<void> register(
  1. AirAdapter adapter
)

Register an adapter with full lifecycle management.

Lifecycle:

  1. Check dependencies
  2. Call onBind(AirDI) — synchronous service registration
  3. Call onInit(AirDI) — async initialization
  4. Add to registered adapters

Throws StateError if a required dependency adapter is not registered.

Implementation

Future<void> register(AirAdapter adapter) async {
  if (_adapters.any((a) => a.id == adapter.id)) {
    debugPrint('AdapterManager: Adapter ${adapter.id} already registered');
    return;
  }

  // Check required dependencies
  for (final depSpec in adapter.dependencies) {
    final parts = depSpec.split(':');
    final depId = parts[0];
    final versionReq = parts.length > 1 ? parts[1] : null;

    final depAdapter = _adapters.where((a) => a.id == depId).firstOrNull;
    if (depAdapter == null) {
      throw StateError(
        'AdapterManager: Adapter "${adapter.id}" requires "$depId" '
        'but it is not registered. Register dependencies first.',
      );
    }

    // Version compatibility check
    if (versionReq != null) {
      if (!_checkVersionCompatibility(depAdapter.version, versionReq)) {
        debugPrint(
          '\x1B[33m[AdapterManager] Warning: Adapter "${adapter.id}" requires "$depId" '
          'version $versionReq, but ${depAdapter.version} is installed.\x1B[0m',
        );
      }
    }
  }

  try {
    final di = AirDI();

    // Synchronous binding
    adapter.onBind(di);

    // Async initialization
    await adapter.onInit(di);

    // Only add after successful initialization
    _adapters.add(adapter);

    debugPrint(
      'AdapterManager: Adapter ${adapter.id} v${adapter.version} registered successfully',
    );
    notifyListeners();
  } catch (e, st) {
    adapter.onError(e, st);
    debugPrint(
      'AdapterManager: Failed to initialize adapter ${adapter.id}: $e',
    );
    rethrow;
  }
}