dispose method
Dispose the controller and clean up ALL resources - PREVENTS MEMORY LEAKS
Implementation
@mustCallSuper
void dispose() {
  if (_disposed) return;
  final stats = getResourceStats();
  ZenLogger.logDebug('Controller $runtimeType disposing... '
      'Resources: ${stats['reactive_objects']} reactive, ${stats['workers']} workers, '
      '${stats['effects']} effects, ${stats['disposers']} disposers');
  try {
    // Call user lifecycle method first
    onClose();
  } catch (e, stack) {
    ZenLogger.logError(
        'Error in onDispose for controller $runtimeType', e, stack);
  }
  // Mark as disposed early to prevent new operations
  _disposed = true;
  // Stop observing app lifecycle if we were
  stopObservingAppLifecycle();
  // ⭐ CRITICAL: Dispose all reactive objects first - PREVENTS MEMORY LEAKS
  _disposeReactiveObjects();
  // Dispose all workers efficiently
  _cleanupAllWorkers();
  // Dispose all effects
  _cleanupEffects();
  // Call all disposers
  _runDisposers();
  // Clear update listeners
  _updateListeners.clear();
  ZenLogger.logDebug('Controller $runtimeType disposed successfully');
  if (ZenConfig.enablePerformanceMetrics) {
    ZenMetrics.incrementCounter('controller.disposed');
  }
}