GetX:依赖的顺序问题-Binding+LazyPut

  1. 问题一:在Controller里面注入依赖
  2. 问题二:依赖的顺序问题
  3. 正确做法使用Binding
  4. 使用LazyPut

问题一:在Controller里面注入依赖

// 创建了 PostApi 
class PostApi extends GetConnect {
  @override
  void onInit() {
    httpClient.baseUrl = "https://jsonplaceholder.typicode.com";
    super.onInit();
  }

  Future<Response> getPosts() => get("/posts");
}

//  创建 Controller
class PostController extends GetxController with StateMixin<List<dynamic>> {
  // final PostApi api = Get.find<PostApi>();
  final PostApi api = PostApi();

  void fetchPosts() async {
    // 发送请求,但是response没有返回值
  	final response = await api.getPosts();
    
  }
}

上面这么写的问题:GetX 可能会提前实例化 PostApi

当在 Controller 里写 final PostApi api = Get.put(PostApi());,每次 Controller 被创建时,PostApi 也会被创建或注入。这样 PostApi 的生命周期就和 Controller 绑定在一起——Controller 什么时候创建,PostApi 就什么时候创建。

App 启动时,Flutter 框架、GetX 容器、网络环境等都需要初始化。如果你在 Controller 构造时就 new 或注入 PostApi,可能此时 App 还没完成所有初始化(比如 runApp 还没执行,GetX 容器还没准备好),导致 PostApi 的 onInit、baseUrl、httpClient 等配置还没生效。

这样 PostApi 虽然被创建了,但它的配置和依赖可能还没准备好,网络请求就会异常(比如 baseUrl 没有设置,GetConnect 没有注册到容器,导致请求路径错误或请求发不出去)。

问题二:依赖的顺序问题

Future<void> main() async { 
  // Get.put(CountController()); 
  final PostController controller = Get.put(PostController()); 
  final PostApi api = Get.put(PostApi()); runApp(MyApp()); 
}

PostController 里面用到了PostApi

我上面这么写,会先创建PostController 再创建PostApi

但是在PostController里面有这么一段代码

// 成员变量
final PostApi api = Get.find<PostApi>();

那么我在创建PostController的时候,会去IOC容器里面找PostApi,可是这个时候PostApi还没有被创建也没有被注册到容器汇总,就会发生报错。

正确顺序应该是先 put PostApi,再 put PostController

final PostApi api = Get.put(PostApi());
final PostController controller = Get.put(PostController());

正确做法使用Binding

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.put(PostApi()); // PostApi 先注册
    Get.put(PostController()); // PostController 再注册(内部安全依赖 PostApi)
  }
}

依赖顺序可控

  • 你在 dependencies() 里按顺序写,GetX 就按顺序执行。
  • 不会出现 AController 先执行 onInit() 时找不到 BController 的情况。

和路由强绑定

  • 每个页面进入时,GetX 自动执行 Binding,不需要你在 main() 或某个地方手动管理。
  • 依赖和页面解耦,项目更清晰。

生命周期安全

  • 页面关闭时,对应的 Controller 会自动释放(除非设置 permanent: truefenix: true)。

团队协作友好

  • 只要看某个页面的 Binding,就能知道它依赖了哪些控制器。
  • 避免了“到处 Get.put() / Get.find() 导致乱”的问题。

使用LazyPut

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.LazyPut(PostController());
    Get.LazyPut(PostApi()); 
  }
}

对于一些依赖比较复杂的情况,我们可以使用懒加载。它的好处是,在Get.LazyPut的时候不会马上创建实例,需要用到的时候(Get.find)才会去创建。这样创建的顺序自然就是依赖创建的顺序,自然而然不需要关注依赖的注入顺序

另外一点,不会一次性把所有依赖都初始化,减少内存占用和启动耗时,性能也得到了优化

×

喜欢就点赞,疼爱就打赏