jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.38k stars 1.62k forks source link

Service locator runtime compile-safe #450

Closed ldasilva-net closed 4 years ago

ldasilva-net commented 4 years ago

The are situations when we need a Controller and Get.find return Exception because we didn`t instance on a superior level or we drop the Controller when we release a View who is owner. This kind of situations is not something particular to Get, it's common to a Service Locators pattern.

But doing research I found a new "state manager/service locator" called riverpod (https://riverpod.dev/ - https://github.com/rrousselGit/river_pod) who promise a compile-safe approach: They say, "if your code compiles, it works.". Its a very nice feature really.

So I wonder, its possible for Get DI made this feature? Do the logic for the compiler to catch these possible exceptions so they don't happen at runtime?

Prn-Ice commented 4 years ago

Doesn't fenix mode cover this.

Prn-Ice commented 4 years ago

Also, I believe controllers are being auto disposed because of gets focus on efficiency, have you tried setting auto-dispose to false.

jonataslaw commented 4 years ago

I honestly think that this can bring more problems than a solution. I did not look deeply into the code of this package, but I cannot imagine anything with 90 controllers being inserted globally as in the example. Exceptions are not a problem. The source code for Flutter has hundreds of them. There is a good reason for asserts and throws in the world today, and tests exist for just that. I don't think it helps in the security of the code, because it induces people not to test them. I don't think it solves a problem (at least the way it was done). I don't think I could do a better solution of this, because I wouldn't spend time trying. GetInstance is not a service locator, although it can act as one. I don't think it solves a problem without creating a bigger one, and certainly between Provider and RiverPod, I prefer a thousand times how Provider works. Finally, making the code work is easy, the hard part is making it work efficiently. What you call "problem", is caused by the controllers' disposition to free memory, everything would work without asserts if I used Getx as a service-locator, and leave everything in memory forever. Anyway, I don't intend to create more of the same, I think that Flutter already has too many state managers and service locators, and I wouldn't be creating another option to compete with riverpod. If someone likes how it is made, they can just use it. Getx's proposal is to solve real Flutter problems, facilitating syntax, improving the RAM consumption of applications with the minimum work done, reducing the use of code generators to increase productivity, and not creating a solution for each existing service.

ldasilva-net commented 4 years ago

Doesn't fenix mode cover this. Also, I believe controllers are being auto disposed because of gets focus on efficiency, have you tried setting auto-dispose to false.

I can't see how. The idea is not make a Controller lives on the hole app always, I think the auto-dispose is completely necesary. The idea is prevent ask for a Object that may be disposed before at compile time, avoiding runtime Errors.

I honestly think that this can bring more problems than a solution. I did not look deeply into the code of this package, but I cannot imagine anything with 90 controllers being inserted globally as in the example.

Mmm they aren't. The approach is similar to Provider, with Hooks for make more readable code.

Exceptions are not a problem. The source code for Flutter has hundreds of them. There is a good reason for asserts and throws in the world today, and tests exist for just that. I don't think it helps in the security of the code, because it induces people not to test them.

Why? Compilation errors detect wrong code also but don't avoid make test anyway.

I don't think it solves a problem (at least the way it was done). I don't think I could do a better solution of this, because I wouldn't spend time trying. GetInstance is not a service locator, although it can act as one. I don't think it solves a problem without creating a bigger one, and certainly between Provider and RiverPod, I prefer a thousand times how Provider works. Finally, making the code work is easy, the hard part is making it work efficiently. What you call "problem", is caused by the controllers' disposition to free memory, everything would work without asserts if I used Getx as a service-locator, and leave everything in memory forever. Anyway, I don't intend to create more of the same, I think that Flutter already has too many state managers and service locators, and I wouldn't be creating another option to compete with riverpod. If someone likes how it is made, they can just use it. Getx's proposal is to solve real Flutter problems, facilitating syntax, improving the RAM consumption of applications with the minimum work done, reducing the use of code generators to increase productivity, and not creating a solution for each existing service.

I think I expressed myself wrong. I'm not thinking of making a comparison between libraries, neither modify the internal functionality of the Get DI. I mention the RiverPod library only because I like the idea for to help avoid this kind of errors.

Prn-Ice commented 4 years ago
Get.lazyPut<HomeController>(() => HomeController(), fenix: true);
GetX<HomeController>(
    builder: (_) => Text(_.var),
  )

Any issues with this.

jonataslaw commented 4 years ago

There are 3 modes of smartManagement. If you want more control, just switch to onlyBuilders, and make the logic of the dispose in assignId / autoremove or keepFactory.

Fenix mode already prevents 99% of these errors, and errors means that you are doing something wrong.

If you are going to test you do not need to worry about anything you are worrying about, as problems will certainly not go through the tests due to Getx's asserts and throws covering all chances of failure.

I think I shouldn't go that way, for me this "security at compile time" in something that is not done through a linter, it is just marketing, and as I said earlier, for me the important thing is not to make the code work, but to make it work efficiently. That way I'm closing it.