Изучение
Начало работы
Установите usecase_forge, выполните типизированный Command и проследите его полный жизненный цикл.
Начало работы
Безопасная версия SDK
Для сборки и распространения приложений используйте Dart 3.13.7+ или Flutter 3.47.8+. Это первые исправленные stable-версии для инцидента eMudhra; в дальнейшем выбирайте актуальный поддерживаемый SDK с исправлениями безопасности.
Минимальная версия в pubspec описывает совместимость API, а не безопасность старой среды исполнения. Пакеты проверены на Dart 3.13.7 и Flutter 3.47.8 без изменения публичного API. Новая версия библиотеки не исправляет уже установленное приложение: затронутые Android, Windows и Linux приложения нужно пересобрать и распространить заново.
Проверьте SDK в IDE, локальной сборке и CI. Обновление глобального SDK на компьютере не гарантирует, что конкретный проект или CI использует именно его. Не отключайте проверку сертификатов для обхода ошибок TLS.
Создадим UseCase счётчика. Пример невелик, но использует те же команду, контекст выполнения, снимок, конечную фазу и закрытие, что и производственная операция.
Требования
- Dart SDK 3.13.7 или более новая поддерживаемая stable-версия с исправлениями безопасности.
- Dart-проект с
pubspec.yaml.
Установка
dart pub add usecase_forge
import 'package:usecase_forge/usecase_forge.dart';
State и Command
Состояние — прикладное значение. UseCase Forge не требует базового класса, но содержательное равенство предотвращает лишние публикации.
final class CounterState {
const CounterState(this.value);
final int value;
@override
bool operator ==(Object other) =>
other is CounterState && other.value == value;
@override
int get hashCode => value.hashCode;
}
final class Increment extends UseCaseCommand {
const Increment({this.by = 1});
final int by;
}
Команда описывает намерение. Она не выполняет сама себя и не хранит состояние интерфейса.
Регистрация обработчика Command
final class CounterUseCase extends UseCase<CounterState> {
CounterUseCase() : super(initialState: const CounterState(0)) {
registerCommand<Increment>(_increment);
}
Future<void> _increment(
Increment command,
UseCaseExecutionContext<CounterState> context,
) async {
final current = context.snapshot.state.value;
context.publish(CounterState(current + command.by));
}
}
Регистрация связывает тип Command с обработчиком. context.snapshot предоставляет Snapshot, доступный текущему Execution, а context.publish публикует новый State в установленном порядке.
Выполнение и закрытие
Future<void> main() async {
final counter = CounterUseCase();
final finished = counter.stream.firstWhere(
(snapshot) => snapshot.phase == UseCaseExecutionPhase.finished,
);
counter.add(const Increment(by: 2));
await finished;
print(counter.state.state.value);
await counter.close();
}
add передаёт намерение. Владелец наблюдает жизненный цикл через снимки и дескрипторы выполнения, а затем обязан дождаться close.