“This is the seventh day of my participation in the First Challenge 2022.

GetX dependency injection

  • GetX integration and Usage of Flutter application framework
  • Flutter dissects the implementation of Getx dependency management step by step through the source code
  • Use of Flutter GetX dependency injection in detail
  • The use of Flutter GetX dependency injection tag is explained

This article will introduce the function and use of Bindings in GetX dependency injection.

role

Bindings is mainly used together with GetX routes and dependencies to inject the dependencies required by the current page when the route jump page is loaded. The advantage of Bindings is that the page dependencies can be managed uniformly. When a page needs to inject a large number of dependencies, it is more convenient to maintain the page dependencies by using Bindings.

use

Bindings need to be used together with GetX route, and GetX route is divided into ordinary route and alias route, next see how to use them respectively.

It is preferred to create a custom Bindings that inherits from Bindings, such as a counter interface, and create a CounterBindings that inject a CounterController into the Dependencies method as follows:

class CounterBinding extends Bindings {
  @override
  voiddependencies() { Get.lazyPut(() => CounterController()); }}Copy the code

The same injection that was done with lazyPut lazy loading can also be done with any of the other injection methods described earlier.

Common routing

Bindings are easy to use for normal routes. You can add a binding parameter to a custom Bindings object.

Get.to(CounterPage(), binding: CounterBinding());

Get.off(CounterPage(), binding: CounterBinding());

Get.offAll(CounterPage(), binding: CounterBinding());
Copy the code

When routing to CounterPage, the dependencies method of CounterBinding is automatically called to initialize the corresponding dependencies. Get. Find gets the injected CounterController object as normal in CounterPage.

The alias routing

Create a GetPage to determine the relationship between the alias and the page and configure it into getPages of GetMaterialApp. When used, route jumps are performed via get. toNamed, and the get. toNamed method has no binding parameters to be passed in.

The Bindings object needs to be passed in when the GetPage is created, as follows:

GetPage(name: "/counter", page: () => CounterPage(), binding: CounterBinding());
Copy the code

The same effect can be achieved by using get.tonamed normally when jumping.

Get.toNamed("/counter");
Copy the code

There is another difference between aliased route and ordinary route. Ordinary route has only one binding parameter and can only pass one Bindings object, while aliased route has one Bindings parameter besides binding parameter. The Bindings array can be passed. Use as follows:

GetPage(
  name: "/counter",
  page: () => CounterPage(),
  binding: CounterBinding(),
  bindings: [PageABinding(), PageBBinding(), PageCBinding()]);
Copy the code

What’s the function of Bindings? Why do we need to pass in an array?

Usually a page only needs one Bindings dependency to manage the page, but when nested components such as ViewPager are used or page nesting exists, Since the nested pages in the page are not loaded by route, the dependencies method of the Bindings cannot be automatically called to initialize the dependencies, and the nested pages may also need to be displayed separately. In order to improve the reusability of the page, the Bindings will also be created for the nested page. In this way, the Bindings of nested pages can be passed into the Bindings of the main page route when the page is nested, as follows:

/// ViewPager page routing
GetPage(
  name: "/viewpager",
  page: () => ViewPagerPage(),
  binding: ViewPagerBinding(),
  bindings: [PageABinding(), PageBBinding(), PageCBinding()]);

/// Separate PageA pageB pageC route
GetPage(
  name: "/pageA",
  page: () => PageAPage(),
  binding: PageABinding(),);
GetPage(
  name: "/pageB",
  page: () => PageBPage(),
  binding: PageBBinding(),);
GetPage(
  name: "/pageC",
  page: () => PageCPage(),
  binding: PageCBinding(),);

/// use
Get.toNamed("/viewpager");

Get.toNamed("/pageA");
Get.toNamed("/pageB");
Get.toNamed("/pageC");
Copy the code

This way, the dependencies of nested pages in the ViewPager can be initialized when used in the ViewPager, and the dependencies can be loaded when a Page is used alone.

The principle of

In front of the Bindings role and use methods, the following simple analysis of the principle of Bindings through the source code.

Bindings is an abstract class, and dependencies is an abstract method.

abstract class Bindings {
  void dependencies();
}
Copy the code

After registering Bindings in page routing, the Dependencies method of Bindings is called during page initialization, which initializes page dependencies in GetPageRoute’s buildContent, GetPageRoute is the PageRoute inherited from Flutter, which is called when a route jump loads the page content.

Widget _getChild() {
  if(_child ! =null) return_child! ;final middlewareRunner = MiddlewareRunner(middlewares);

  /// For Bindings
  final localbindings = [
    if(bindings ! =null)... bindings! .if(binding ! =null) ...[binding!]
  ];
  /// Call the onBindingsStart method of the middleware
  final bindingsToBind = middlewareRunner.runOnBindingsStart(localbindings);
  
  /// Call the Bindings dependencies method
  if(bindingsToBind ! =null) {
    for (final binding inbindingsToBind) { binding.dependencies(); }}finalpageToBuild = middlewareRunner.runOnPageBuildStart(page)! ; _child = middlewareRunner.runOnPageBuilt(pageToBuild());return_child! ; }@override
Widget buildContent(BuildContext context) {
  return _getChild();
}
Copy the code

The core code of the source code is to get the Bindings passed in when the page widgets are created and then call the Dependencies method of the Bindings in turn.

Among them:

  /// For Bindings
  final localbindings = [
    if(bindings ! =null)... bindings! .if(binding ! =null) ...[binding!]
  ];
  /// Call the onBindingsStart method of the middleware
  final bindingsToBind = middlewareRunner.runOnBindingsStart(localbindings);
  
  /// Call the Bindings dependencies method
  if(bindingsToBind ! =null) {
    for (final binding inbindingsToBind) { binding.dependencies(); }}Copy the code

Bindings and bindings passed in the route are fetched into the same array. Then call the Dependencies method in turn, where binding is the binding parameter passed in route or GetPage, and Bindings is the array passed in GetPage when alias routes are used.

conclusion

This paper introduces the functions and usage methods of Bindings in GetX dependency injection, analyzes the implementation principle of Bindings with the source code of GetX, and further understands why Bindings can achieve page dependency injection management. We hope that we can better understand Bindings in GetX through the source code, so that we can flexibly use the Bindings management page dependencies in the development.