使用篇
原理篇
一、 依赖注入的介绍
是什么:本来接受各种参数来构造一个对象,现在只接受一个参数——已经实例化的对象。
目的:依赖注入是为了将依赖组件的配置和使他分离开,来降低使用者与依赖之间的耦合度。
实现依赖项注入可为您带来以下优势:
- 重用代码 更容易换掉依赖项的实现。由于控制反转,代码重用得以改进,并且类不再控制其依赖项的创建方式,而是支持任何配置。
- 易于重构 依赖项的创建分离,可以在创建对象时或编译时进行检查、修改,一处修改,使用处不需修改。
- 易于测试 类不管理其依赖项,因此在测试时,您可以传入不同的实现以测试所有不同用例。
二、GetX依赖注入的方式
GetX依赖注入有四种方式:
1、 put
我们大部分时候使用的就是put,在调用的时候已经注入到内存中了,而且默认返回的是一个单例。如果想返回不同的实例对象,可以设置tag参数。
S put<S>(
// [dependency] 被注入的对象,S 表示可以是 任何类型的
S dependency,
{
// [tag] 可选地,使用 [tag] 作为“id”来创建相同类型的多个记录,
// [tag] 不会与其 他依赖项类型使用的相同标签冲突
String? tag,
// 将 Instance 保存在内存中并将其持久化,而不遵循 `Get.smartManagement` 规则。
// 虽然,可以通过 `GetInstance.reset()` 和 `Get.delete()` 删除
bool permanent = false,
// 可选:允许你使用函数而不是依赖(dependency)本身来创建依赖。
InstanceBuilderCallback<S>? builder
}) =>
GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
Get.put(User(), tag: "user");
Get.put(User(), tag: "user1");
User user = Get.find(tag: "user");
User user1 = Get.find(tag: "user1");
print("Get.put 获取的对象比较 ${user == user1}");
可以看到给put加上不同的tag的话,它返回的就是不同的实例对象了。还有就是put的一个参数
permanent ,对于需要对象存活较久的,就可以设置为true,不然的话一般为false就行了。
2、lazyPut
这个是懒加载意思是只有当你find的时候,才会注入一个依赖对象。在计算比较高昂的类或者
你不知道这个类什么时候用, 还有就是你想在一个地方实例化几个类(比如在Bindings类中),就可以使用这个方法。
lazyPut<S>(
//当你的类第一次被调用时,将被执行的方法。
InstanceBuilderCallback<S> builder,
{
//当不想让同一个类有多个不同的实例时,就会用到它,必须是唯一的
String? tag,
//下次使用的时候是否重建,设为true的时候,当不使用的时候,实例就会被删除,再次find的时候就会重新创建实例
//就像 bindings api 中的 "SmartManagement.keepFactory "一样。
bool fenix = false}
)
3、 putAsync
Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
{String? tag, bool permanent = false}) async =>
GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
Get.put() 的异步版本。等待来自 builder()参数的 Future 解析并存储返回的 实例。
一般这样使用:
Get.putAsync<SharedPreferences>(() async {
final prefs = await SharedPreferences.getInstance();
return prefs;
});
4、 create
void create<S>(InstanceBuilderCallback<S> builder,
{String? tag, bool permanent = true}) =>
GetInstance().create<S>(builder, tag: tag, permanent: permanent);
使用这个方法,表示你每次find的时候,都会创建一个新的实例对象,跟上面Get.put是有所区别的。它还将每个 `instance.onClose()` 注册到当前的路由 `GetConfig.currentRoute` ,以保持生命周期处于活动状态。要知道创建的实例仅存储每个路由。因此,如果您调用 `Get.delete<T>()`,此方法中使用的“实例工厂”(`Get.create<T>()`)将被删除,但不会删除已由它创建的实例。意思就是说, 你的路由必须要使用Get的路由,创建的对象会和当前widget的周期绑定,当widget被dispose的时候,这个实例对象就会被回收。如果使用原生路由实例对象是不会被回收的。
Get.create(() => User());
//Get.put(User());
User user = Get.find();
User user1 = Get.find();
print("Get.create 获取的对象比较 ${user == user1}"); false
// print("Get.put 获取的对象比较 ${user == user1}"); true
三、Bindings的用法
在没有使用Bindings类之前,我都是要在widget里面去手动实现依赖注入的。所以说widget类和依赖还存在没有解耦的情况。因此就有了Bindings类的出现,这个类可以将路由、状态管理器和依赖管理器完全集成。
bindings有两种使用方式
1、直接新建一个类继承Bindings类,然后实现dependencies方法,放进要注入的实例对象就行了。
class TestBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => TestController());
}
}
Binding的子类要可以在路由跳转的时候这样写 Get.to(()=>TestPage,binding:TestBinding())。
如果你使用的是命名路由的话,你可以这样写:
GetPage(
name: test,
page: () => TestPage(),
binding: TestBinding())
2、第二种方式就是使用BindingsBuilder ,如果你不想每次都新建一个Bindings类的话,你可以这样写
GetPage(
name: test,
page: () => TestPage(),
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,可以根据自己的编码风格来使用。如果对你有用话,欢迎点赞关注!