I'm relatively new to Flutter and Cubit pattern and I'm trying to figure out which are the best ways to work with them. Recently my colleague and I have been struggling to reach an agreement where we should inject the cubit and the repositories.
Reading the bloc/cubit documentation, it is not very clear about where we should do it.
IMO, everything that we need to instantiate, should be injected as high in the tree as possible where two different components that will use this information have in common.
For my colleague, each widget can instantiate one cubit, meaning that each widget will have its own instance of the cubit.
I would like to discuss about what are the community thoughts and best practices regarding the dependency injection and architecture regarding cubit.
There is no single answer to that question. It all depends on your project structure and architecture. In general though:
It's OK to create a few cubits/blocs in one screen/widget. Some widgets or screens contain more than one business logic stuff. Cubits are just classes that help you maintain the state, but it's no different than having many animation controllers or text editing controllers, it's just that it serves a more high-level state management. Let's say that you have a comments section in your app. You may have:
It's perfectly valid to have it that way.
It's OK to have global cubits for the whole app. There are some things that you need to have access to from the whole application. It usually is navigation (Navigator
), and some theme management (Theme
), why not something more business-logic related then, like authentication logic, current user context, user's app preferences, etc.? :)
IMO, everything that we need to instantiate, should be injected as high in the tree as possible where two different components that will use this information have in common.
This is a good approach. Most frequently it will be above your routes, so somewhere above your MaterialApp
. If you make use of nested Navigator
s, then this common place could be above this nested Navigator
.
On a more technical side, how will you manage the dependencies used in those cubits/blocs is up to you and your liking. I find some of the options:
Instantiating all repositories and other dependencies in main.dart
method and then passing them in constructors to your blocs/cubits in Provider
s.
To reload those dependencies you will need a Hot Restart though, Hot Reload won't be enough.
Putting your dependencies in the widget's tree with Provider
, just like blocs/cubits.
Using riverpod
instead of provider
.
Using a Service Locator pattern with get_it
and injectable
combo.
The most correct choice will be something that you (and your colleagues) are most comfortable developing with and that scales well.