Question #14MediumState Management

Getx Binding

#getx

Answer

Overview

GetX Bindings are classes that group your dependency injections for a specific route/screen. They ensure controllers are created when navigating to a screen and disposed when leaving — automatically.


Why Use Bindings?

Without Bindings, you manually call

text
Get.put()
in every screen. Bindings centralize DI per route, making code cleaner and controllers automatically lifecycle-managed.


Creating a Binding

dart
// bindings/home_binding.dart
class HomeBinding extends Bindings {
  
  void dependencies() {
    // All dependencies for HomeScreen
    Get.lazyPut<HomeController>(() => HomeController());
    Get.lazyPut<UserRepository>(() => UserRepository());
    Get.lazyPut<ApiService>(() => ApiService());
  }
}

Attaching Binding to a Route

dart
// routes/app_pages.dart
class AppPages {
  static final routes = [
    GetPage(
      name: '/',
      page: () => HomeScreen(),
      binding: HomeBinding(), // ← Attached here
    ),
    GetPage(
      name: '/profile',
      page: () => ProfileScreen(),
      binding: ProfileBinding(),
    ),
    GetPage(
      name: '/checkout',
      page: () => CheckoutScreen(),
      bindings: [ // Multiple bindings
        CheckoutBinding(),
        PaymentBinding(),
      ],
    ),
  ];
}

Using the Controller in the Screen (No Get.put needed)

dart
class HomeScreen extends StatelessWidget {
  // Controller is already injected by HomeBinding
  final controller = Get.find<HomeController>(); // Just find it

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Obx(() => Text('Count: ${controller.count}')),
    );
  }
}

BindingsBuilder (Inline Without Separate Class)

dart
GetPage(
  name: '/settings',
  page: () => SettingsScreen(),
  binding: BindingsBuilder(() {
    Get.lazyPut<SettingsController>(() => SettingsController());
  }),
)

Initial Binding (App-level DI)

dart
void main() {
  runApp(GetMaterialApp(
    initialBinding: AppBinding(), // App-wide dependencies
    home: HomeScreen(),
  ));
}

class AppBinding extends Bindings {
  
  void dependencies() {
    Get.put<AuthService>(AuthService(), permanent: true); // Lives forever
    Get.lazyPut<ApiService>(() => ApiService());
  }
}

Binding Lifecycle

text
User navigates to /profile
ProfileBinding.dependencies() is called
ProfileController is created (lazyPut — on first use)
User is on ProfileScreen
User navigates back
ProfileController.onClose() is called
ProfileController is disposed (garbage collected)

Best Practice: Always use Bindings with named routes — it gives automatic controller lifecycle management, cleaner code, and easier testing (you can mock dependencies in Bindings).