Concepts de base
The package intentionally narrows features ? keep behavior explicit: provider identity by args, scoped injection, et predictable disposal semantics.
What Changes de Riverpod
Instead de generated family classes et implicit notifier channels, miniriverpod prefers subclass + args + explicit invoke.
Provider identity
runtimeType + args hash
family alternative
Subclass Provider / AsyncProvider et pass super.args((...))
DI fallback
Scope<T>.required + overrideWithValue
Why this matters
You can reason about equality et overrides de plain Dart constructors, which keeps debugging et tests straightforward.
Provider Identity avec args
args defines the provider key, so equal args means the same cache entry inside a ProviderContainer.
Identity rule
ProviderKey = runtimeType + hash(args)
Practical consequences
- No dedicated family type is required.
- Per-argument override is done by creating provider instances.
- Keep args stable and immutable for predictable caching.
exemple: family-like provider + Scope fallback
Use a constructor argument as identity et inject a fallback instance through Scope.
class ProductProvider extends AsyncProvider<List<Product>> {
ProductProvider({this.search = ''}) : super.args((search,));
final String search;
static final fallback = Scope<ProductProvider>.required('product.fallback');
@override
FutureOr<List<Product>> build(ref) async {
final api = ref.watch(productsApiProvider);
return api.search(q: search);
}
}
// Inject
ProviderScope(
overrides: [
ProductProvider.fallback.overrideWithValue(ProductProvider(search: 'jeans')),
],
child: const App(),
);
?tapes suivantes
providers & Reads
See concrete patterns pour watch/read/listen et AsyncProvider.future.
Open providers