docs(disposable): add detailed English documentation and usage examples for Disposable interface; chore: update binding_resolver and add explanatory comment in scope_test for deprecated usage.\n\n- Expanded Disposable interface docs, added sync & async example classes, and CherryPick integration sample.\n- Clarified how to implement and use Disposable in DI context.\n- Updated binding_resolver for internal improvements.\n- Added ignore for deprecated member use in scope_test for clarity and future upgrades.\n\nBREAKING CHANGE: Documentation style enhancement and clearer API usage for Disposable implementations.

This commit is contained in:
Sergey Penkovsky
2025-08-11 11:53:25 +03:00
parent 450f4231cb
commit 4d872d7c25
3 changed files with 71 additions and 4 deletions

View File

@@ -1,3 +1,16 @@
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'dart:async'; import 'dart:async';
typedef Instance<T> = FutureOr<T>; typedef Instance<T> = FutureOr<T>;

View File

@@ -1,10 +1,63 @@
/// Базовый интерфейс для автоматического управления ресурсами в CherryPick. //
/// Если объект реализует [Disposable], DI-контейнер вызовет [dispose] при очистке scope. // Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'dart:async'; import 'dart:async';
/// Interface for resources that need to be disposed synchronously or asynchronously. /// An interface for resources that require explicit cleanup, used by the CherryPick dependency injection container.
///
/// If an object implements [Disposable], the CherryPick DI container will automatically call [dispose]
/// when the corresponding scope is cleaned up. Use [Disposable] for closing streams, files, controllers, services, etc.
/// Both synchronous and asynchronous cleanup is supported:
/// - For sync disposables, implement [dispose] as a `void` or simply return nothing.
/// - For async disposables, implement [dispose] returning a [Future].
///
/// Example: Synchronous Disposable
/// ```dart
/// class MyLogger implements Disposable {
/// void dispose() {
/// print('Logger closed!');
/// }
/// }
/// ```
///
/// Example: Asynchronous Disposable
/// ```dart
/// class MyConnection implements Disposable {
/// @override
/// Future<void> dispose() async {
/// await connection.close();
/// }
/// }
/// ```
///
/// Usage with CherryPick DI Module
/// ```dart
/// final scope = openRootScope();
/// scope.installModules([
/// Module((b) {
/// b.bind<MyLogger>((_) => MyLogger());
/// b.bindAsync<MyConnection>((_) async => MyConnection());
/// }),
/// ]);
/// // ...
/// await scope.close(); // will automatically call dispose on all Disposables
/// ```
///
/// This pattern ensures that all resources are released safely and automatically when the scope is destroyed.
abstract class Disposable { abstract class Disposable {
/// Releases all resources held by this object. /// Releases all resources held by this object.
/// For sync disposables, just implement as void; for async ones, return Future. ///
/// Implement cleanup logic (closing streams, sockets, files, etc.) within this method.
/// Return a [Future] for async cleanup, or nothing (`void`) for synchronous cleanup.
FutureOr<void> dispose(); FutureOr<void> dispose();
} }

View File

@@ -95,6 +95,7 @@ class AsyncModule extends Module {
@override @override
void builder(Scope scope) { void builder(Scope scope) {
bind<AsyncCreatedDisposable>() bind<AsyncCreatedDisposable>()
// ignore: deprecated_member_use_from_same_package
.toProvideAsync(() async { .toProvideAsync(() async {
await Future.delayed(Duration(milliseconds: 10)); await Future.delayed(Duration(milliseconds: 10));
return AsyncCreatedDisposable(); return AsyncCreatedDisposable();