Summarizing dependency injection with GetX

In this chapter on dependency injection with GetX, we were introduced to the concept of dependency injection and learned the various methods and approaches provided by GetX to inject dependencies into classes. We explored helper widgets that separate the presentation layer from the dependency initialization layer and learned how to configure dependency disposal. In this summary lesson, we will revisit the key concepts and important points from all the lessons of this chapter. So, let’s go through each lesson one by one.

Introduction to dependency injection

  • Overview:

    • Design pattern for supplying dependencies to classes or functions from external sources.

    • Benefits include decoupling, modularity, testability, reusability, flexibility, and configurability.

  • Basic dependency injection:

    • Dependencies passed through class constructors.

    • Example: class First and class Second demonstrating dependency injection through constructor parameters.

  • Dependency injection in Flutter:

    • Dependencies passed through widget constructors.

    • Example: Widget1 and Widget2 using constructor parameters to pass dependencies in the widget tree.

  • Dependency injection in GetX:

    • Controller creation:

      • Create a controller class with dependencies.

      • Example: Controller with a name variable.

    • Initialization:

      • Initialize controller using Get.put() in a widget.

      • Example: Widget1 initializing Controller with Get.put().

    • Accessing dependencies:

      • Access controller instance using Get.find() in other widgets.

      • Example: Widget2 accessing Controller instance with Get.find().

Bindings

  • Overview:

    • Classes for initializing dependencies and binding them to routes in GetX.

    • Separates dependency initialization from the presentation layer, enhancing code organization.

  • Creating a bindings class:

    • Implement the Bindings class and override its dependencies method.

    • Initialize dependencies using dependency injection methods such as Get.put, Get.lazyPut, or Get.putAsync.

  • Binding to route:

    • Connect the bindings class to a route using GetPage’s binding parameter.

    • Incorporates GetX route management for efficient binding.

  • Using dependencies:

    • Access dependencies in widgets using Get.find().

    • Dependencies initialized in the bindings class become available for child widgets.

  • Other connection methods:

    • Bind dependencies while navigating with Get.to or Get.toNamed.

    • Declare initialBinding to initialize dependencies on app start.

    • Utilize BindingsBuilder for injecting dependencies without separate classes.

Get.put

  • Overview:

    • Initializes dependencies for the first time, making them available throughout the widget tree.

  • Basic usage:

    • Call Get.put to inject a dependency, which can then be accessed directly in the class.

    • Eliminates the need to manually call Get.find to use the dependency.

  • Multiple shared instances:

    • Utilizes tags to group instances into shared instance groups.

    • Allows multiple instances with the same type but different states to coexist.

  • Preserving dependencies:

    • By default, dependencies are deleted when the associated widget is disposed of.

    • Set the permanent property to true to preserve dependencies throughout the app’s life cycle.

Get.lazyPut

  • Lazy loading dependencies:

    • Dependencies are initialized instantly but allocated memory only when accessed.

    • Improves memory efficiency by loading dependencies only when needed by a widget.

  • Conditionally initializing dependencies:

    • Uses builder parameter to conditionally initialize dependencies.

    • Offers flexibility to choose between different dependency instances based on conditions.

  • Multiple shared instances:

    • Utilizes the tag parameter to create multiple shared instance groups of the same dependency.

    • Each shared instance group is lazy loaded individually, enhancing memory optimization.

  • Reloading dependencies:

    • By default, dependencies are not reloaded into memory if deleted.

    • Set the fenix parameter to true to reload dependencies when needed, improving memory management.

Get.putAsync

  • Initializing dependencies asynchronously:

    • Initializes dependencies asynchronously, allowing for operations like fetching data from API.

    • Uses a builder function to initiate asynchronous processes and obtain dependency instances.

    • Returns a Future representing the asynchronous operation, which resolves to the dependency instance once complete.

  • Retrieving dependencies:

    • Dependencies initialized asynchronously are retrieved using Get.find once the asynchronous operation completes.

  • Similarities with Get.put:

    • Supports creating multiple shared instances using tag parameter.

    • Offers the option to preserve dependencies throughout the app life cycle by setting the permanent parameter to true.

Get.create

  • Overview:

    • Creates new instances of dependencies every time Get.find is called.

    • Useful for maintaining separate states of the same class across different widgets.

  • Example:

    • Utilize Get.create for scenarios like a shopping cart where each item maintains its own state.

  • Multiple shared instances:

    • Supports multiple shared instances using the tag parameter, similar to Get.put.

  • Preserving dependency deletion

    • Dependencies injected by Get.create are preserved from deletion by default.

    • Includes a permanent parameter to explicitly mark dependencies as non-permanent.

Get.replace

  • Overview:

    • Resolves the challenge of re-injecting dependencies by replacing the original dependency with a new one.

    • Useful for scenarios requiring dynamic changes to dependency instances.

  • Leveraging with inherited classes:

    • Enables using inherited classes with different implementations, providing flexibility in dependency management.

  • Replacing specific instances:

    • Supports replacing specific instances of dependencies injected with the same tag, providing granular control over dependency replacement.

Get.lazyReplace

  • Overview:

    • Allows lazy replacement of dependencies, meaning the new dependency is injected only when accessed for the first time via Get.find.

    • Internally utilizes Get.lazyPut for dependency injection.

  • Features:

    • Conditionally replacing dependencies: Enables dynamic initialization of dependencies based on specific conditions using a builder pattern.

    • Replacing specific instances: Supports replacing specific instances of dependencies injected with the same tag, offering granular control over dependency replacement.

    • Reloading dependencies: Provides memory management options similar to Get.lazyPut, allowing deleted dependencies to be reinjected when needed again.

GetView and GetWidget

  • Overview:

    • Simplify access to controllers in widgets without manually calling Get.find.

    • GetView provides a stateless widget with an instance of the specified controller.

    • GetWidget offers the same functionality as GetView but maintains a consistent reference to the same dependency instance.

  • GetView:

    • Declares a controller instance internally, named controller, for easy access in the widget tree.

    • Suitable for widgets depending on a single controller.

  • GetWidget:

    • Provides the same instance of Get.find every time, ensuring consistent reference to the dependency.

    • Ideal for scenarios where maintaining a single dependency instance is crucial, such as with Get.create.

Configurations for dependency disposal

  • Overview:

    • GetX provides SmartManagement configurations to control the disposal of dependencies from memory.

  • Full mode:

    • Deletes all controllers completely when the attached route or widget is disposed of.

    • Controllers initialized lazily won’t be re-initialized if needed again.

  • Keep factory mode:

    • Retains the factory of controllers, allowing re-initialization if a widget needs them again.

    • Relevant for controllers initialized lazily using Get.lazyPut without bindings or inside initialBinding.

  • Only builder mode:

    • Preserves all controllers except those initialized by GetBuilder and GetX widgets using the init parameter.

    • Controllers initialized using Get.lazyPut inside a binding class also get deleted but will re-initialize if needed again.

Choosing the right injection

  • Get.put: Most commonly used method, provides immediate injection and the ability to prevent deletion.

  • Get.lazyPut: Ideal for memory management, load dependencies lazily and conditionally, and re-initialize deleted dependencies.

  • Get.putAsync: Ideal for long lived services, injects dependencies asynchronously and conditionally, prevents deletion.

  • Get.create: Maintains each widget state independently, creates a new instance on every call of Get.find, and prevents deletion by default.

  • Get.replace: Replace previously injected dependencies, for example, a controller with its child controller.

  • Get.lazyReplace: Replace dependencies lazily and conditionally, re-initialize replaced dependencies.

Get hands-on with 1400+ tech skills courses.