Flutter依赖注入插件injectable_micropackages的使用
Flutter依赖注入插件injectable_micropackages的使用
Injectable 是一个用于 get_it 的便捷代码生成器。它受到 Angular DI、Guice DI 和 inject.dart 的启发。
目录
安装
在 pubspec.yaml
文件中添加以下依赖:
dependencies:
# 添加 injectable 到你的依赖项
injectable:
# 添加 get_it
get_It:
dev_dependencies:
# 添加生成器到你的 dev_dependencies
injectable_generator:
# 当然需要 build_runner 来运行生成器
build_runner:
设置
- 创建一个新的 Dart 文件,并定义一个全局变量来存储你的 GetIt 实例。
- 定义一个顶级函数(我们称之为
configureDependencies
),并用@injectableInit
注解它。 - 调用生成的函数
$initGetIt()
或自定义初始化名称,并将getIt
实例传递进去。 - 在
main
函数中调用configureDependencies()
,并在运行应用之前执行。
final getIt = GetIt.instance;
@InjectableInit(
initializerName: r'$initGetIt', // 默认值
preferRelativeImports: true, // 默认值
asExtension: false, // 默认值
)
void configureDependencies() => $initGetIt(getIt);
// 如果你想告诉 injectable 处理特定目录内的文件,可以使用 generateForDir 属性
// 例如,只处理 test 文件夹中的文件
@InjectableInit(generateForDir: ['test'])
void configureDependencies() => $initGetIt(getIt);
void main() {
configureDependencies();
runApp(MyApp());
}
注册工厂
所有你需要做的就是使用 [@injectable](/user/injectable)
注解你的可注入类,并让生成器完成工作。
[@injectable](/user/injectable)
class ServiceA {}
[@injectable](/user/injectable)
class ServiceB {
ServiceB(ServiceA serviceA);
}
运行生成器
使用 [watch]
标志来监视文件系统中的更改,并根据需要重新构建。
flutter packages pub run build_runner watch
如果只想运行一次生成器并退出,则使用:
flutter packages pub run build_runner build
生成文件内部
Injectable 将为你生成所需的注册函数。
final getIt = GetIt.instance;
void $initGetIt(GetIt getIt, {String environment, EnvironmentFilter environmentFilter}) {
final gh = GetItHelper(getIt, environment);
gh.factory<ServiceA>(() => ServiceA());
gh.factory<ServiceB>(ServiceA(getIt<ServiceA>()));
}
注册单例
使用 [@singleton](/user/singleton)
或 @lazySingleton
注解你的单例类。
[@singleton](/user/singleton) // 或者 @lazySingleton
class ApiProvider {}
注册异步注入对象
如果实例化需要异步操作,你将需要一个静态初始化方法,因为构造函数不能是异步的。
class ApiClient {
static Future<ApiClient> create(Deps ...) async {
....
return apiClient;
}
}
现在只需使用 [@injectable](/user/injectable)
注解你的类,并使用 [@factoryMethod](/user/factoryMethod)
注解来告诉 injectable 使用静态初始化方法作为工厂方法。
[@injectable](/user/injectable) // 或者 lazy/singleton
class ApiClient {
[@factoryMethod](/user/factoryMethod)
static Future<ApiClient> create(Deps ...) async {
....
return apiClient;
}
}
生成的代码:
factoryAsync<ApiClient>(() => ApiClient.create());
传递参数给工厂
如果你的工作涉及一个你可以控制的类,只需使用 @factoryParam
注解你的可变构造函数参数即可。最多可以有两个参数!
[@injectable](/user/injectable)
class BackendService {
BackendService(@factoryParam String url);
}
生成的代码:
factoryParam<BackendService, String, dynamic>(
(url, _) => BackendService(url),
);
绑定抽象类到实现
使用 [@Injectable](/user/Injectable)(as: ..)
注解内的 as
属性来传递由注册依赖项实现的抽象类型。
[@Injectable](/user/Injectable)(as: Service)
class ServiceImpl implements Service {}
// 或者
@Singleton(as: Service)
class ServiceImpl implements Service {}
// 或者
@LazySingleton(as: Service)
class ServiceImpl implements Service {}
生成的代码:
factory<Service>(() => ServiceImpl())
注册在不同环境下的对象
通过使用 @Environment('name')
注解来注册不同环境下的不同依赖项。
@Environment("dev")
[@injectable](/user/injectable)
class ServiceA {}
或者,你可以通过 env
属性来分配环境名到你的依赖项。
[@Injectable](/user/Injectable)(as: Service, env: [Environment.dev, Environment.test])
class RealServiceImpl implements Service {}
``
### 使用命名工厂和静态创建函数
默认情况下,injectable 将使用默认构造函数来构建你的依赖项,但你可以通过 `[@factoryMethod](/user/factoryMethod)` 注解来告诉 injectable 使用命名构造函数或静态创建函数。
```dart
[@injectable](/user/injectable)
class MyRepository {
[@factoryMethod](/user/factoryMethod)
MyRepository.from(Service s);
}
生成的代码:
factory<MyRepository>(MyRepository.from(getIt<Service>()))
注册第三方类型
为了注册第三方类型,创建一个抽象类并使用 [@module](/user/module)
注解,然后添加你的第三方类型作为属性访问器或方法。
[@module](/user/module)
abstract class RegisterModule {
[@singleton](/user/singleton)
ThirdPartyType get thirdPartyType;
[@prod](/user/prod)
[@Injectable](/user/Injectable)(as: ThirdPartyAbstract)
ThirdPartyImpl get thirdPartyType;
}
自动注册
通过使用约定优于配置的方式,可以在微包架构中自动注册你的可注入类。
targets:
$default:
builders:
injectable_generator:injectable_builder:
options:
auto_register: true
class_name_pattern: "Service$|Repository$|Bloc$"
file_name_pattern: "_service$|_repository$|_bloc$"
示例
import 'package:injectable/injectable_annotations.dart';
abstract class Service {}
[@named](/user/named)
[@prod](/user/prod)
[@Injectable](/user/Injectable)(as: Service)
class ServiceImpl1 extends Service {}
[@Injectable](/user/Injectable)(as: Service, env: [Environment.dev])
class ServiceImpl2 implements Service {}
[@injectable](/user/injectable)
class MyRepository {
MyRepository(@Named.from(ServiceImpl1) Service service);
}
更多关于Flutter依赖注入插件injectable_micropackages的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter依赖注入插件injectable_micropackages的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用injectable_micropackages
插件来实现依赖注入的代码示例。injectable_micropackages
是一个流行的Flutter依赖注入库,它基于get_it
包,但提供了更多的功能和简化配置。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加injectable
和get_it
的依赖:
dependencies:
flutter:
sdk: flutter
injectable: ^2.0.0 # 请检查最新版本号
get_it: ^7.2.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置Injectable
创建一个新的Dart文件,例如injection.dart
,来配置Injectable:
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
// 创建GetIt实例
final getIt = GetIt.instance;
@InjectableConfig(
asLazySingleton: true,
)
class MyInjectableConfig {}
void setupLocator() {
// 注册依赖
getIt.registerLazySingleton<MyService>(() => MyServiceImpl());
getIt.registerLazySingleton<MyRepository>(() => MyRepositoryImpl(getIt<MyService>()));
}
3. 创建服务和仓库
接下来,创建你的服务和仓库类,并使用@Injectable()
注解标记它们:
import 'package:injectable/injectable.dart';
@Injectable()
abstract class MyService {
Future<String> fetchData();
}
class MyServiceImpl implements MyService {
@override
Future<String> fetchData() async {
// 模拟数据获取
await Future.delayed(Duration(seconds: 2));
return "Data fetched!";
}
}
@Injectable()
abstract class MyRepository {
Future<String> getDataFromService();
}
class MyRepositoryImpl implements MyRepository {
final MyService _service;
MyRepositoryImpl(this._service);
@override
Future<String> getDataFromService() async {
return await _service.fetchData();
}
}
4. 在应用入口初始化
在你的应用入口文件(通常是main.dart
)中,调用setupLocator
来初始化依赖注入:
import 'package:flutter/material.dart';
import 'injection.dart';
void main() {
// 初始化依赖注入
setupLocator();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
final myRepository = getIt<MyRepository>();
myRepository.getDataFromService().then((data) {
print(data); // 输出: Data fetched!
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Injectable Example'),
),
body: Center(
child: Text('Check console for fetched data'),
),
);
}
}
5. 运行应用
现在你可以运行你的Flutter应用。你应该会在控制台中看到输出"Data fetched!"
,这表明依赖注入已成功实现。
总结
通过以上步骤,你已经成功在Flutter项目中使用injectable_micropackages
插件实现了依赖注入。这个插件大大简化了依赖管理的复杂性,并提供了强大的功能来支持复杂的应用架构。