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

Why do we need get_it? #188

Closed
zommerberg opened this issue May 7, 2021 · 6 comments
Closed

Why do we need get_it? #188

zommerberg opened this issue May 7, 2021 · 6 comments

Comments

@zommerberg
Copy link

zommerberg commented May 7, 2021

I do not understand the benefits of using get_it or InheritedWidget.

I've looked into why we need InheritedWidget, this solves the data passing problem. However for that we have a state management system so we do not need InheritedWidget at all.

I've looked into get_it and from my understanding if we are already using a state management system the only benefit we would have is the ability to encapsulate the services/methods related to a chunk of widgets into one place. (dependency injection)

For example if we have a map and a locate me button then they could share the same _locateMe service.

For this we would create an abstract class that defines the _locateMe method and connect it with the dependency injection using a locator.registerLazySingleton.

But what is the point? I can just create a methods.dart file with the locateMe method without any classes, we can just put the method into the methods.dart which is faster and easier and we can access it from anywhere.

I am not sure how dart internally works, what makes sense for me is that registerLazySingleton would remove the _locateMe method from memory after I use the _locateMe method. And if we put the locateMe method inside a normal .dart file without classes or anything else it will be always in memory hence less performant.

Is my assumption true? Is there something I am missing?

@escamoteur
Copy link
Collaborator

Let me put it this way, you are not completely wrong. You definitely can use just global functions and global variables to make state accessible to your UI.
The real power of dependency injection comes from using abstract interface classes when registering the types. This allows you to switch implementations at one time without changing any other part of your code.
This is especially helpful when it comes to write unit tests or UI tests so that you can easily inject mock objects.

Another aspect is scoping of the objects. Inherited widgets as well as get_it allow you to override registered objects based on a current scope. For inherited widgets this scope is defined by your current position in the widget tree, in get_it you can push and pop registrations scopes independent of the widget tree.

Scopes allow you to override existing behaviour or to easily manage the lifetime and disposal of objects.

The general idea of any dependency injection system is that you have defined point in your code where you have all your setup and configuration.
Furthermore GetIt helps you initialise your synchronous business objects while automatically care for dependencies between such objects.

You wrote your already using some sort of state management solution. Which probably means that the solution already offer some sort of object location. In this case you probably won't need get_it.
Together with the get_it_mixin however you don't need any other state management solution if you already use get_it.

I hope this could clarify your question a bit.

@escamoteur escamoteur pinned this issue May 7, 2021
@zommerberg
Copy link
Author

zommerberg commented May 7, 2021

@escamoteur Thank you! This clarifies it a lot.

Lastly this doesn't affect memory, right?
Performance wise is it still the same when comparing to a basic method definition?

@escamoteur
Copy link
Collaborator

yeah that is right. But by using scopes e.g. it's easier to make sure that objects that you no longer need are freed. If they are global variables they never will be freed unless you assign null to them.

@zommerberg
Copy link
Author

Awesome, thanks a ton!

@phamquoctrongnta
Copy link

yeah that is right. But by using scopes e.g. it's easier to make sure that objects that you no longer need are freed. If they are global variables they never will be freed unless you assign null to them.

Sorry for my grammar :)
Assume I registered 3 dependent classes for the first time. (For example: LoginController, HomeController, ProfileController).
On the first screen, I only use 1 class via GetIt.I.get().
Does HomeController and ProfileController consume memory?

@escamoteur
Copy link
Collaborator

@ntaworking If you register them with registerSingleton they will consume memory. If you want to avoid that you can use registerLazySingleton then the classes will only created the first time you use them.

However unless your classes create thousands of objects when created or load 100 images, you rarely should worry about the memory that your own classes consume. Our current phones have more than enough.

It's a different thing if the creation of these classes takes a lot of time then it can make sense to use a lazy Singleton to speed up startup time. But in such cases it's often better to use an async registration and await the finish of all initialization using allReady see https://github.com/fluttercommunity/get_it#asynchronous-singletons

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