Skip to content

Providers

A provider is a tool that helps manage and inject dependencies in an application, making it easier to share data or services across different parts of the app.

Providers

Declare a new provider either as a global final variable or a final static field.

Example with a global final variable:

/// global scope
final numberProvider = Provider((context) => 5);

If there is only a provider per class, you can also create a final static field. This comes down to personal preference.

class MyDatabase {
static final provider = Provider((context) => MyDatabase());
}

Injection of other providers with context

Providers can leverage the context to inject other providers. The context will be relative to the scope in which they are provided.

final doubleNumberProvider = Provider((context) {
final number = numberProvider.of(context);
return number * 2;
});

Providers with argument

Providers need to be provided before they can be injected in the widget tree. Sometimes, they need an initial argument so that they can be instantiated correctly. This is possible with Provider.withArgument.

final numberPlusArgProvider = Provider.withArgument((context, int arg) {
return 5 + arg;
});

An example where this might make more sense would be an application with multi-account support, where the database is loaded per user, and the filepath of the database contains the user ID:

class MyDatabase {
static final provider = Provider.withArgument((context, String userId) => MyDatabase.fromId(id));
}

This MyDatabase.provider has to be provided in a subtree (of the widget tree) belonging to the currently logged user.

Injection of other providers with context

Providers can both take an argument and rely on context.

final doubleNumberPlusArgProvider = Provider.withArgument((context, int arg) {
final number = numberProvider.of(context);
return number * 2 + arg;
});

Dispose and lazy parameters

When defining a provider, we need to pass the positional create argument, which is a function used to generate the value contained by the provider.

There are also two optional named parameters that can be specified.

ParameterDefaultDescription
disposenullThe function to call when the scope containing the provider gets disposed. It is used to dispose correctly the value held by the provider.
lazyDiscoConfig.lazy, which defaults to trueThe provider’s value is created lazily, meaning it is only created when first injected.