Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provider.shared for Efficient SharedInstance Management #872

Open
dadagov125 opened this issue Mar 17, 2024 · 4 comments
Open

Provider.shared for Efficient SharedInstance Management #872

dadagov125 opened this issue Mar 17, 2024 · 4 comments
Assignees
Labels
enhancement New feature or request needs triage

Comments

@dadagov125
Copy link

dadagov125 commented Mar 17, 2024

Is your feature request related to a problem? Please describe.

During the development of mobile applications using the Flutter framework, a common task is to organize efficient navigation between screens and manage the application state effectively. A particularly pressing issue arises when there is a need to transfer and reuse specific instances for state management, services, or data across different screens. For instance, consider a scenario where we have two screens: ScreenA and ScreenB, between which we need to pass and utilize the same instance for state management.

A traditional approach involves creating and initializing instances at a level that is above all screens, such as in the global state of the application or above MaterialApp. This allows instances to be accessible anywhere in the application. However, this approach has a significant drawback: the instance remains in memory for the entire lifecycle of the application, even when not in use. This leads to inefficient resource usage, especially in cases where the instance is only needed for a short period or in a limited context.

An alternative approach, which involves directly passing instances between screens via navigation arguments, also has its limitations. Firstly, it can be cumbersome when working with complex data structures or a large amount of data that needs to be passed. Secondly, with the use of declarative navigation and routing, this approach can complicate the navigation architecture, making the code less readable and maintainable.

Developers thus face a dilemma: how to ensure efficient reuse of instances between screens without unnecessarily loading memory and complicating navigation logic. The solution should offer a flexible mechanism for managing the lifecycle of instances, allowing them to be created as needed and resources to be freed when they are no longer necessary, thereby optimizing memory usage and improving the performance of the application.

Passing data between screens via navigation arguments is limited and not always suitable for working with complex data structures or in the context of declarative navigation.

Describe the solution you'd like
To enhance the capabilities of provider in Flutter, it is proposed to add functionality that allows providers to manage shared instances, such as state objects or services:

  1. Centralized Repository: Implement a repository for shared instances so that providers can facilitate access to them.

  2. Instance Reuse: Providers should check for the presence of a required instance in the repository and reuse it if available. If the instance is absent, the provider creates a new one and adds it to the repository.

  3. Lifecycle Management: Providers automatically remove instances from the repository when they are no longer in use.

These improvements will enable more efficient resource use and simplify working with shared instances in the application.

Describe alternatives you've considered
Considered alternatives:

  1. Direct instance transfer between screens: Directly passing instances through arguments during screen transitions. This method is simple but becomes inconvenient with an increase in the amount of data.

  2. Global instances: Using global variables or singletons for instance access. Easy to implement but can lead to memory management issues.

  3. Provider above MaterialApp: Placing provider at the top level of the widget tree for global instance access. Ensures availability but doesn't address the issue of inefficient memory use.

Additional context

@rrousselGit
Copy link
Owner

Honestly I'll admit that I'd like to refrain from adding new APIs to Provider.

I'm not fond of the proposed Provider.shared API, because it is in many ways just a singleton. We wouldn't be able to have a different value for the provider based on the current route for example.
This feels counter to what InheritedWidget try to do, as being able to have a different value based on the current route is one of the main benefits over plain singletons.

Also, another challenge could be that two routes may define the a Provider<A>.shared, but have a different implementation for it. This could be source of confusion.

In Riverpod, the way it solves this problem is by still defining providers above MaterialApp. But instead offering autoDispose, to dispose of providers when they are no-longer in use.

@dadagov125
Copy link
Author

I understand the concerns regarding adding a new API like Provider.shared to Provider due to its similarity to singletons and potential issues with different values for different routes. Also the issue of potential confusion when two routes might define Provider<A>.shared with different implementations is indeed significant.

However, introducing instanceKey in Provider.shared could address this issue. Utilizing instanceKey would allow for the unambiguous identification of instances even when they are used in different parts of the application. Making the instanceKey parameter mandatory could further reduce the likelihood of confusion, ensuring clarity and preventing unintended overlapping of instances.

This enhancement to the Provider.shared API could offer a flexible solution for managing shared instances without compromising the ability to have different values depending on the route and minimizing the risk of confusion between different implementations of instances.

@dadagov125
Copy link
Author

We could also consider adding a separate class, such as SharedProvider, to encapsulate this functionality

@rrousselGit
Copy link
Owner

First of, I assume folks would be able to implement this without any change to pkg:provider. Am I right?
My guess is folks could make custom Provider widgets that use pkg:provider's widgets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs triage
Projects
None yet
Development

No branches or pull requests

2 participants