Sparround

The provider tree: create, .value, dispose

package:provider describes itself as a wrapper around InheritedWidget to make them easier to use and more reusable. In practice it does three things: it places an object in the tree, manages its lifetime, and gives readers a subscription.

The main provider kinds:

  • Provider — an object that never changes (a repository, a service, configuration).
  • ChangeNotifierProvider — listens to a ChangeNotifier and updates dependents when notifyListeners() fires.
  • ListenableProvider, ValueListenableProvider — for other Listenable types.
  • FutureProvider, StreamProvider — for async sources.
  • ProxyProvider — a provider whose value depends on another provider.
  • MultiProvider — the flat list form that avoids deep nesting; the docs recommend it for readability.
ConstructorWhenDisposal
`ChangeNotifierProvider(create: ...)`You **create** the object here`dispose()` is called automatically when the provider leaves the tree
`ChangeNotifierProvider.value(value: ...)`The object **already exists** (created elsewhere, or a fake in a test)The provider does not dispose it — whoever owns it is responsible

A direct warning from the docs: do not use the .value constructor to create an object — it can produce undesired side effects; conversely, handing an existing object to create may call its dispose while it is still in use. The rule to remember: `create` = I create it, the provider disposes it; `.value` = someone else created it, the provider must not touch it.

dart
void main() {
  final api = ApiClient(); // tətbiqin ömrü boyu yaşayır

  runApp(
    MultiProvider(
      providers: [
        // Dəyişməyən obyekt: yalnız ötürülür.
        Provider<ApiClient>.value(value: api),

        // Repository api-dan asılıdır → ProxyProvider.
        ProxyProvider<ApiClient, TodoRepository>(
          update: (_, client, previous) => previous ?? TodoRepository(client),
        ),

        // State: burada yaradılır, ona görə provider dispose edəcək.
        ChangeNotifierProvider(
          create: (context) => CartModel(context.read<TodoRepository>()),
        ),

        // lazy: false → ilk oxunuşu gözləmədən dərhal yaradılır.
        ChangeNotifierProvider(
          create: (_) => AuthModel()..restoreSession(),
          lazy: false,
        ),
      ],
      child: const MyApp(),
    ),
  );
}

A typical root: services and notifiers inside MultiProvider.

📚 Sources and documentation