The goal of the provider framework is to inject dependencies into your app without recreating them all the time. In your example, you have your HiveDB class which is what you want to inject into your app for various other widgets to use it.
IMO, the general approach of "providing" dependencies is:
- Create dependency instances outside the app (Typically in the
main() function)
- Create a provider which injects this dependency object
- Wrap your
MaterialApp with the provider
- Supply your dependency object into the provider wrapper
- Use the
Provider<DependencyClass>.of(context) to access your dependency wherever you need it in your app.
Let's see how this applies to your code:
1. Setup your Hive models and HiveDB
lib/models/event_box.dart
@HiveType(typeId: 0)
class EventsBox extends HiveObject {
@HiveField(0)
DateTime date;
@HiveField(1)
List<CleanCalendarEvent> eventsList;
EventsBox({
required this.date,
required this.eventsList,
});
}
lib/models/hive_db.dart
class HiveDB {
var _events;
HiveDB._create() {}
static Future<HiveDB> create() async {
final component = HiveDB._create();
await component._init();
return component;
}
_init() async {
Hive.registerAdapter(EventsBoxAdapter());
this._events = await Hive.openBox<EventsBox>('events');
}
storeEvent(EventsBox eventsMap) {
this._events.put('events', eventsMap);
}
EventsBox getEvents() {
return this._events.get('events');
}
}
In this case, you want to "provide" (or inject) an instance of HiveDB to your app.
2. Create a provider for your HiveDB instance
lib/models/hive_db_provider.dart
class HiveDbProvider extends StatelessWidget {
final HiveDB db;
final Widget child;
const HiveDbProvider({
Key? key,
required this.db,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<HiveDB>.value(
value: db,
child: Consumer<AppCache>(
builder: (context, db, _) {
return child;
},
),
);
}
}
3. Create HiveDB instance in main()
lib/main.dart
void main() async {
final HiveDB db = await HiveDB.create();
runApp(
MyApp(db: db)
);
}
...
4. Inject the HiveDB instance using the provider
lib/main.dart
...
class MyApp extends StatelessWidget {
final HiveDB db;
const PayBuddy({
Key? key,
required this.db,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return HiveDbProvider(
db: db,
child: CacheProvider(
cache: cache,
child: MaterialApp(
...
),
),
);
}
}
5. Access "provided" instance using Provider anywhere in your app
lib/pages/some_screen.dart
import "package:provider/provider.dart";
...
class SomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Access HiveDB instance
final hiveDb = Provider<HiveDB>.of(context);
...
}
}
Conclusion
The sample uses the Provider package which simplifies using provider usage in Flutter.