• flutter 身兼数职的getx —— 依赖管理


    一、 依赖注入的介绍


    是什么:本来接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象。
    目的:依赖注入是为了将依赖组件的配置和使他分离开,来降低使用者与依赖之间的耦合度。
    实现依赖项注入可为您带来以下优势:

    • 重用代码 更容易换掉依赖项的实现。由于控制反转,代码重用得以改进,并且类不再控制其依赖项的创建方式,而是支持任何配置。
    • 易于重构 依赖项的创建分离,可以在创建对象时或编译时进行检查、修改,一处修改,使用处不需修改。
    • 易于测试 类不管理其依赖项,因此在测试时,您可以传入不同的实现以测试所有不同用例。

     
    二、GetX依赖注入的方式

      GetX依赖注入有四种方式:

    1、 put 

    我们大部分时候使用的就是put,在调用的时候已经注入到内存中了,而且默认返回的是一个单例。如果想返回不同的实例对象,可以设置tag参数。

    1.   S put(
    2. // [dependency] 被注入的对象,S 表示可以是 任何类型的
    3. S dependency,
    4.           {
    5. // [tag] 可选地,使用 [tag] 作为“id”来创建相同类型的多个记录,
    6. // [tag] 不会与其 他依赖项类型使用的相同标签冲突
    7. String? tag,
    8. // 将 Instance 保存在内存中并将其持久化,而不遵循 `Get.smartManagement` 规则。
    9. // 虽然,可以通过 `GetInstance.reset()``Get.delete()` 删除
    10.           bool permanent = false,
    11. // 可选:允许你使用函数而不是依赖(dependency)本身来创建依赖。
    12.           InstanceBuilderCallback? builder
    13. }) =>
    14.       GetInstance().put(dependency, tag: tag, permanent: permanent);
    1. Get.put(User(), tag: "user");
    2. Get.put(User(), tag: "user1");
    3. User user = Get.find(tag: "user");
    4. User user1 = Get.find(tag: "user1");
    5. print("Get.put 获取的对象比较 ${user == user1}");

     
     

     可以看到给put加上不同的tag的话,它返回的就是不同的实例对象了。还有就是put的一个参数

    permanent ,对于需要对象存活较久的,就可以设置为true,不然的话一般为false就行了。

    2、lazyPut 

     这个是懒加载意思是只有当你find的时候,才会注入一个依赖对象。在计算比较高昂的类或者

    你不知道这个类什么时候用, 还有就是你想在一个地方实例化几个类(比如在Bindings类中),就可以使用这个方法。

    1. lazyPut(
    2. //当你的类第一次被调用时,将被执行的方法。
    3. InstanceBuilderCallback builder,
    4. {
    5. //当不想让同一个类有多个不同的实例时,就会用到它,必须是唯一的
    6. String? tag,
    7. //下次使用的时候是否重建,设为true的时候,当不使用的时候,实例就会被删除,再次find的时候就会重新创建实例
    8. //就像 bindings api 中的 "SmartManagement.keepFactory "一样。
    9. bool fenix = false}
    10. )

    3、  putAsync

    1. Future<S> putAsync<S>(AsyncInstanceBuilderCallback builder,
    2. {String? tag, bool permanent = false}) async =>
    3. GetInstance().putAsync(builder, tag: tag, permanent: permanent);

    Get.put() 的异步版本。等待来自 builder()参数的 Future 解析并存储返回的 实例。

    一般这样使用:

    1. Get.putAsync(() async {
    2. final prefs = await SharedPreferences.getInstance();
    3. return prefs;
    4. });

    4、 create
     

    1. void create(InstanceBuilderCallback builder,
    2. {String? tag, bool permanent = true}) =>
    3. GetInstance().create(builder, tag: tag, permanent: permanent);

    使用这个方法,表示你每次find的时候,都会创建一个新的实例对象,跟上面Get.put是有所区别的。它还将每个 `instance.onClose()` 注册到当前的路由 `GetConfig.currentRoute` ,以保持生命周期处于活动状态。要知道创建的实例仅存储每个路由。因此,如果您调用 `Get.delete()`,此方法中使用的“实例工厂”(`Get.create()`)将被删除,但不会删除已由它创建的实例。意思就是说, 你的路由必须要使用Get的路由,创建的对象会和当前widget的周期绑定,当widget被dispose的时候,这个实例对象就会被回收。如果使用原生路由实例对象是不会被回收的。

    1. Get.create(() => User());
    2. //Get.put(User());
    3. User user = Get.find();
    4. User user1 = Get.find();
    5. print("Get.create 获取的对象比较 ${user == user1}"); false
    6. // print("Get.put 获取的对象比较 ${user == user1}"); true

              

    三、Bindings的用法

    在没有使用Bindings类之前,我都是要在widget里面去手动实现依赖注入的。所以说widget类和依赖还存在没有解耦的情况。因此就有了Bindings类的出现,这个类可以将路由、状态管理器和依赖管理器完全集成。

    bindings有两种使用方式

    1、直接新建一个类继承Bindings类,然后实现dependencies方法,放进要注入的实例对象就行了。

    1. class TestBinding extends Bindings {
    2. @override
    3. void dependencies() {
    4. Get.lazyPut(() => TestController());
    5. }
    6. }

    Binding的子类要可以在路由跳转的时候这样写 Get.to(()=>TestPage,binding:TestBinding())。

     如果你使用的是命名路由的话,你可以这样写:

    1. GetPage(
    2. name: test,
    3. page: () => TestPage(),
    4. binding: TestBinding())

    2、第二种方式就是使用BindingsBuilder ,如果你不想每次都新建一个Bindings类的话,你可以这样写

    1. GetPage(
    2. name: test,
    3. page: () => TestPage(),
    4. binding: BindingsBuilder(() => [Get.lazyPut(() => TestController())]))

    还有就是也可以写在 GetMaterialApp里面。这个里面也定义了一个binding参数,叫initialBinding。这个跟上面的用法是一样的。不同的是,不需要跟页面进行绑定。

    GetX 默认情况下会将未使用的控制器从内存中移除。 但是如果你想改变GetX控制类的销毁方式,你可以用SmartManagement类设置不同的行为。

    • SmartManagement.full 这是默认的。销毁那些没有被使用的、没有被设置为永久的类。在大多数情况下,我们都使用这个,不需要更改。

    • SmartManagement.onlyBuilders 使用该选项,只有在init:中启动的控制器或用Get.lazyPut()加载到Binding中的控制器才会被销毁。

      如果使用Get.put()或Get.putAsync()或任何其他方法,SmartManagement 没有权限也就是不能移除这个依赖。

    • SmartManagement.keepFactory 就像SmartManagement.full一样,当它不再被使用时,它将删除它的依赖关系,但它将保留它们的工厂,这意味着如果再次需要该实例,它将重新创建该依赖关系。

    四、总结

    对于依赖注入有四种方式,我们要根据不同的业务场景来使用相应的方法就可以了。对于Bindings,可以根据自己的编码风格来使用。如果对你有用话,欢迎点赞关注!

  • 相关阅读:
    APCS (Arm Procedure Call Standard) 过程调用标准
    护理管理学选择题汇总(人卫第三版)
    Reactor 模式
    我的创作纪念日-第256天
    20_Vue如何监测数组类型数据发生改变的?
    【深度学习】Beam Search原理和实现、闲聊机器人优化
    MATLAB : Plot函数及其用法
    Flutter 中的 CupertinoUserInterfaceLevel 小部件:全面指南
    【luogu P4218】珠宝商(SAM)(点分治)(根号分治)
    Pandas-01(安装、Series及DataFrame介绍)
  • 原文地址:https://blog.csdn.net/hjjdehao/article/details/126119363