关于GetIt框架中serviceLocator()作为参数使用的含义疑问
serviceLocator()作为参数使用的含义疑问 嘿,我来给你把这个点讲明白,这其实就是GetIt依赖注入最核心的用法哦~
首先你得知道:serviceLocator是GetIt的实例对象,当你直接调用serviceLocator()的时候,本质上是在调用它的call方法,这个方法的作用就是从GetIt的依赖容器里,取出你已经注册过的对应类型的实例。
咱结合你的代码一条条看:
1. 关于 dio: serviceLocator()
你之前已经用这行代码注册了Dio的实例:
serviceLocator.registerFactory<Dio>(() => NetworkClient(Dio(), constant: serviceLocator()).dio);
当注册NewsApi的时候,构造函数需要一个Dio类型的参数。这里写dio: serviceLocator(),Dart的类型推断会自动识别出这个参数需要的是Dio类型,于是GetIt就会从容器里找到你之前注册的Dio实例,自动注入进去。你要是写成serviceLocator<Dio>()也完全没问题,只是省略类型参数更简洁而已。
2. 关于 newsApi: serviceLocator()
同理,你已经注册了NewsApi的懒加载单例:
serviceLocator.registerLazySingleton<NewsApi>(() => NewsApi(...));
在注册NewsRepositoryImpl时,构造函数需要NewsApi类型的参数,serviceLocator()会通过类型推断,找到容器里的NewsApi实例并注入,省得你手动去创建NewsApi对象,还能保证依赖的统一管理。
3. 关于 GetRecentNewsUseCase(serviceLocator())
GetRecentNewsUseCase的构造函数需要NewsRepository类型的参数,而你之前已经注册了NewsRepository的懒加载单例,所以serviceLocator()会自动匹配到NewsRepository的实例,注入给这个用例类。
额外补充:为什么有的地方要写<Constant>?
比如你代码里的serviceLocator<Constant>().apiKey,这里必须指定<Constant>,因为你要获取Constant实例后访问它的apiKey属性——这种情况没法通过参数类型推断,所以必须明确告诉GetIt你要取哪个类型的实例。
总结一下:
serviceLocator()是serviceLocator.get()的简写,本质都是从容器取依赖- 省略类型参数时,靠Dart的类型推断来匹配对应依赖,代码更简洁
- 这种写法的好处是完全由GetIt管理所有依赖,实现了解耦,后续替换依赖(比如测试用模拟对象)会特别方便
备注:内容来源于stack exchange,提问作者Texter

