df_di 0.15.10 copy "df_di: ^0.15.10" to clipboard
df_di: ^0.15.10 copied to clipboard

A pragmatic dependency injection (DI) system, coupled with service classes for seamless state management in Dart.

example/example.dart

// This example demonstrates dependency injection with df_di.
// ignore_for_file: avoid_print

import 'package:df_di/df_di.dart';

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

/// Example 1: A simple service class to demonstrate DI registration.
class UserService {
  final int id;
  bool _isDisposed = false;

  UserService(this.id);

  Async<Map<String, dynamic>> getUserData() {
    return Async(() async {
      if (_isDisposed) {
        throw Err('UserService has already been disposed!');
      }
      await Future<void>.delayed(const Duration(seconds: 1));
      return {'id': id, 'name': 'John Doe'};
    });
  }

  Async<Unit> dispose() {
    return Async(() async {
      if (_isDisposed) {
        throw Err('UserService has already been disposed!');
      }
      _isDisposed = true;
      print('UserService disposed');
      return Unit();
    });
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

/// Example 2: A Service with lifecycle management.
final class CounterService extends Service {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    print('Count incremented to: $_count');
  }

  @override
  TServiceResolvables<Unit> provideInitListeners(void _) {
    return [
      (_) {
        _count = 0;
        print('CounterService initialized');
        return syncUnit();
      },
    ];
  }

  @override
  TServiceResolvables<Unit> providePauseListeners(void _) {
    return [
      (_) {
        print('CounterService paused');
        return syncUnit();
      },
    ];
  }

  @override
  TServiceResolvables<Unit> provideResumeListeners(void _) {
    return [
      (_) {
        print('CounterService resumed');
        return syncUnit();
      },
    ];
  }

  @override
  TServiceResolvables<Unit> provideDisposeListeners(void _) {
    return [
      (_) {
        print('CounterService disposed with final count: $_count');
        return syncUnit();
      },
    ];
  }
}

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

Future<void> main() async {
  print('=== df_di Example ===\n');

  // --- Part 1: Basic DI with UserService ---
  print('--- Part 1: Basic DI Registration ---');

  UNSAFE:
  {
    // Create a future that waits for UserService to be registered
    final userServiceFuture = DI.global.untilSuper<UserService>().unwrap();

    // Register the service after a delay (simulating async initialization)
    Future.delayed(const Duration(seconds: 1), () {
      DI.global
          .register<UserService>(
            UserService(123),
            onUnregister: (result) {
              if (result.isOk()) {
                final userService = result.unwrap();
                // ignore: void_checks
                return Future.value(userService.dispose().unwrap());
              }
              return null;
            },
          )
          .end;
      print('UserService registered');
    });

    // Wait for the service to be registered
    final userService = await userServiceFuture;

    // Use the service
    final userDataResult = await userService.getUserData().value;
    if (userDataResult.isOk()) {
      print('User data: ${userDataResult.unwrap()}');
    }

    // Unregister the service (triggers dispose via onUnregister)
    final _ = await DI.global.unregister<UserService>().value;
    print('UserService unregistered\n');
  }

  // --- Part 2: Service Lifecycle with CounterService ---
  print('--- Part 2: Service Lifecycle ---');

  // Register CounterService with lifecycle callbacks
  DI.global.register<CounterService>(
    CounterService(),
    onRegister: (service) => service.init(),
    onUnregister: ServiceMixin.unregister,
  );

  // Wait for initialization to complete
  final counterService = await DI.global.untilSuper<CounterService>().unwrap();

  // Use the service
  counterService.increment();
  counterService.increment();
  counterService.increment();
  print('Current count: ${counterService.count}');

  // Demonstrate pause/resume
  await counterService.pause().value;
  await counterService.resume().value;

  // Unregister (triggers dispose via ServiceMixin.unregister)
  await DI.global.unregister<CounterService>().value;
  print('CounterService unregistered\n');

  // --- Part 3: Hierarchical Containers ---
  print('--- Part 3: Hierarchical Containers ---');

  // Register in session container
  DI.session.register<String>('session_token_123');

  // Access from user container (child of session)
  final token = DI.user<String>();
  print('Token from DI.user: $token');

  // Check registration
  print(
    'Is String registered in DI.session? ${DI.session.isRegistered<String>()}',
  );
  print('Is String registered in DI.user? ${DI.user.isRegistered<String>()}');

  // Clean up
  DI.session.unregister<String>();

  print('\n=== Example Complete ===');
}
4
likes
160
points
660
downloads

Publisher

verified publisherdev-cetera.com

Weekly Downloads

A pragmatic dependency injection (DI) system, coupled with service classes for seamless state management in Dart.

Homepage

Topics

#get-it #dependency-injection #services #service-locator #state-management

Documentation

API reference

Funding

Consider supporting this project:

www.buymeacoffee.com
www.patreon.com
github.com
www.patreon.com
github.com
www.buymeacoffee.com

License

MIT (license)

Dependencies

collection, df_debouncer, df_log, df_safer_dart, df_type, equatable, meta

More

Packages that depend on df_di