Skip to content

[Question] How do I change singleton in runtime, replacing it in all dependent instances? #259

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

Closed
Tumist76 opened this issue Feb 23, 2022 · 6 comments

Comments

@Tumist76
Copy link

Tumist76 commented Feb 23, 2022

Let's say I have the following setup in my app:

serviceLocator.registerSingleton<Api>(Api(baseUrl: 'http://google.com'));

Somewhere in the app I use that singleton like this:

...
BlocProvider<LoadingBloc>(
    create: (context) => AppBloc(api: serviceLocator<Api>()),
),
...

In the app lifecycle I need to re-create with singleton with another baseUrl and that's not a problem with unregister() and then calling registerSingleton again but how dependent classes can I use this new singleton?

Is it possible to make new instance of Api class and make dependent class instance (AppBloc in this case) to use that new Api without recreating AppBloc?

@escamoteur
Copy link
Collaborator

First I always find it funny seeing people combine get_it with Provider and then even with Bloc? did you ever check out my get_it_mixin?

But to your question: I don't understand why you think it would be a problem with dependent classes. If you AppBloc accesses API only over the serviceLocator it will always get the current version of you singleton

@Tumist76
Copy link
Author

I don't see anything funny actually in combining get_it with any other kind of state management. In my example it could be any other class I think.
I did check get_it_mixin and it seems straightforward to use it in new project but I'm integrating get_it in existing app now and there's no point in refactoring large chunks of UI and business logic now. But sorry for getting off-topic.

I've created this question because I've tried to implement mentioned behaviour just as I described in the question. I'm using unregister() and registerSingleton() but the BLoC is using old Api instance. This seems right as I don't re-recreate the BLoC itself and Api instance is being passed to constructor.
I understand that I can call serviceLocator<Api>() on every api call inside BLoC but I really want to avoid doing that.

@escamoteur
Copy link
Collaborator

Sorry, I didn't want to insult you.
The problem is that your block would need to have the ability to get notified that an Object it depends on is changed and get_it would need to know which objects reference objects stored inside get_it. I hope you understand that's not a possible way.

If you don't want call serviceLocator<Api>() every time which actually is what I would do, you need to add a subcriber-notification mechanism into you blocks to inform them to update API again from get_it when you need to change the URL.
The way easier method would be not to recreate API but make the URL a mutable field so you could just update that

@escamoteur
Copy link
Collaborator

I know several people combining get_it with other state management solutions. But IMHO using three as in your case is a bit of an overkill. you are using provider as it looks like just as another service locator which could also be done by get_it

@Tumist76
Copy link
Author

Tumist76 commented Feb 23, 2022

Don't worry, i didn't think that was an insult, just a misunderstanding and I understand why now. I don't use Provider, BlocProvider is a part of BLoC package itself. It allows to bind BLoC class to UI, that's all.

Regarding the question, I don't know why, but I thought that maybe there's some magic way to do that. I see that making field mutable is the best way to do so, but there's restrictions imposed by "retrofit" that generated Api class. That's a different topic that shouldn't be in this repo though. Tips taken, I'll think what way would be the most suitable. Thank you for your answers to this newbie question :)

@phucgaoxam
Copy link

@Tumist76 did you find the solution for this? I tried to make an global variable as a mutation field, but getIt still returns the old singleton instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants