Tutorials
Build a feature around one UseCase
Connect one UseCase snapshot to a Model, adapt it with Presenter, and render it through a directly bound MvpView.
Build a feature around one UseCase
This counter feature uses UseCase Forge as an optional business-state source. The MVP packages do not depend on it; application composition imports both systems.
1. Own the business object
A surrounding StatefulWidget creates CounterUseCase and closes it from dispose(). MvpView will not assume that ownership.
2. Define the feature Model
final class CounterModel {
const CounterModel({
required this.snapshot,
required this.increment,
});
final UseCaseSnapshot<CounterState> snapshot;
final void Function() increment;
}
The concrete UseCase does not cross the boundary. Model carries the current snapshot and one permitted operation.
3. Create one stable binding
late final ModelBinding<CounterModel> binding = ModelBinding(
read: () => CounterModel(
snapshot: counter.state,
increment: () => counter.add(const IncrementCounter()),
),
changes: <Stream<Object?>>[counter.stream],
);
Create the binding once for the feature lifecycle. Recreating it on every Flutter build intentionally creates a new Presenter lifecycle.
4. Adapt state in Presenter
Presenter maps value and execution phase into display text and interaction policy. It can use MaterialLocalizations.of(context) while building ViewState because that context is current and is not retained.
The public increment() method either invokes the Model operation or emits CounterLimitReached. View does not repeat the limit rule.
5. Render ready values
Pass the stable binding directly to MvpView. Its builder receives current ViewState and the concrete Presenter. Handle the effect with the active BuildContext, for example through ScaffoldMessenger.
6. Verify the boundary
- View cannot read
CounterModel; - Presenter cannot send an undeclared command;
MvpViewowns Presenter;- the surrounding widget owns and closes the UseCase;
- rebuilding for locale or theme preserves Presenter and rebuilds ViewState.