docs+feat: add Disposable interface source and usage example

feat(core,doc): unified async dispose mechanism for resource cleanup

BREAKING CHANGE:

- Added full support for asynchronous resource cleanup via a unified FutureOr<void> dispose() method in the Disposable interface.
- The Scope now provides only Future<void> dispose() for disposing all tracked resources and child scopes (sync-only dispose() was removed).
- All calls to cleanup in code and tests (scope itself, subscopes, and custom modules) now require await ...dispose().
- Documentation and all examples updated: resource management is always async and must be awaited; Disposable implementers may use both sync and async cleanup.
- Old-style, synchronous cleanup methods have been completely removed (API is now consistently async for all DI lifecycle management).
- Example and tutorial code now demonstrate async resource disposal patterns.
This commit is contained in:
Sergey Penkovsky
2025-08-01 15:07:12 +03:00
parent 61f2268d63
commit a9c95f6a89
14 changed files with 516 additions and 69 deletions

View File

@@ -75,8 +75,54 @@ Example:
// or
final str = rootScope.tryResolve<String>();
// close main scope
Cherrypick.closeRootScope();
// Recommended: Close the root scope & automatically release all Disposable resources
await Cherrypick.closeRootScope();
// Or, for advanced/manual scenarios:
// await rootScope.dispose();
```
### Automatic resource management (`Disposable`, `dispose`)
If your service implements the `Disposable` interface, CherryPick will automatically await `dispose()` when you close a scope.
**Best practice:**
Always finish your work with `await Cherrypick.closeRootScope()` (for the root scope) or `await scope.closeSubScope('feature')` (for subscopes).
These methods will automatically await `dispose()` on all resolved objects implementing `Disposable`, ensuring safe and complete cleanup (sync and async).
Manual `await scope.dispose()` is available if you manage scopes yourself.
#### Example
```dart
class MyService implements Disposable {
@override
FutureOr<void> dispose() async {
// release resources, close connections, perform async shutdown, etc.
print('MyService disposed!');
}
}
final scope = openRootScope();
scope.installModules([
ModuleImpl(),
]);
final service = scope.resolve<MyService>();
// ... use service
// Recommended:
await Cherrypick.closeRootScope(); // will print: MyService disposed!
// Or, to close a subscope:
await scope.closeSubScope('feature');
class ModuleImpl extends Module {
@override
void builder(Scope scope) {
bind<MyService>().toProvide(() => MyService()).singleton();
}
}
```
## Logging