df_di 0.1.0 df_di: ^0.1.0 copied to clipboard
A powerful and versatile dependency injection (DI) system with service classes for easy state management.
//.title
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
//
// Dart/Flutter (DF) Packages by DevCetra.com & contributors. The use of this
// source code is governed by an MIT-style license described in the LICENSE
// file located in this project's root directory.
//
// See: https://opensource.org/license/mit
//
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
//.title~
// ignore_for_file: invalid_use_of_protected_member
import 'dart:async';
import 'package:df_di/df_di.dart';
import 'package:flutter/foundation.dart';
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
void main() async {
if (kDebugMode) {
// Print the current state of di to understand what's registed.
print(di.registry.state); // Nothing registered at this point.
// Register FooBarService as a lazy singleton.
di.registerSingletonService(FooBarService.new);
// Now we have a SingletonInst<FooBarService> registered.
print(di.registry.state);
final fooBarService1 = await di.get<FooBarService>();
// SingletonInst<FooBarService> is gone, now we have a FooBarService registered.
print(di.registry.state);
final fooBarService2 = di<FooBarService>();
final fooBarService3 = di<FooBarService>();
// Same instances, prints true.
print(fooBarService1 == fooBarService2);
print(fooBarService2 == fooBarService3);
di.registerSingletonService(SyncServiceExmple.new);
print(di.get<SyncServiceExmple>() is Future); // false
// Use getSync/getSyncOrNull if you expect a sync.
print(di.getSync<SyncServiceExmple>());
di.registerSingletonService(AsyncServiceExample.new);
print(di.registry.state);
// Use getAsync/getAsyncOrNull if you expect an async.
print(di.getAsync<AsyncServiceExample>());
print(di.registry.state);
di.registerSingletonService(CountingService.new);
final coutingService = di.get<CountingService>();
print(coutingService);
Future.delayed(
const Duration(seconds: 5),
() async {
di.unregisterAll(
(e) {
if (kDebugMode) {
print(e);
}
},
).thenOr((_) {
if (kDebugMode) {
print('Disposed all!');
}
});
},
);
}
}
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
/// A new service class that extends [Service].
///
/// - Register via `di.initSingletonService(FooBarService.new);`
/// - Get via `di.get<FooBarService>();`
/// - Unregister via `di.unregister<FooBarService>();`
final class FooBarService extends Service {
/// Gets [_vFooBar] as a [ValueListenable] to discourage tampering with [ValueNotifier].
ValueListenable<String?> get vFooBar => _vFooBar;
final _vFooBar = ValueNotifier<String?>(null);
@override
FutureOr<void> onInitService() async {
_vFooBar.value = 'FooBar';
}
@override
FutureOr<void> onDispose() {
if (kDebugMode) {
print('Disposed $CountingService');
}
_vFooBar.dispose();
}
}
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
final class CountingService extends StreamingService<int> {
@override
Stream<int> provideInputStream() async* {
for (var n = 0; n < 100; n++) {
await Future<void>.delayed(const Duration(seconds: 1));
yield n;
}
}
@override
void onPushToStream(int data) {
if (kDebugMode) {
print('[CountingService]: $data');
}
}
@override
FutureOr<void> onDispose() {
if (kDebugMode) {
print('Disposed $CountingService');
}
return super.onDispose();
}
}
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// An example of a service that DI will treat as sync.
final class SyncServiceExmple extends Service {
@override
void onInitService() {}
@override
void onDispose() {}
}
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
// An example of a service that DI will treat as async.
final class AsyncServiceExample extends Service {
@override
Future<void> onInitService() async {
await Future<void>.delayed(
const Duration(seconds: 3),
);
}
@override
Future<void> onDispose() async {}
}