Flutter嵌入式配置插件embedded_config的使用
Flutter嵌入式配置插件embedded_config的使用
embedded_config
是一个允许在构建时将应用程序配置直接嵌入到源代码中的包。该插件旨在解决不同构建环境(例如开发环境和生产环境)需要不同应用程序配置的问题。通过使用 Dart 的构建系统(build_runner
),可以为每个环境创建单独的 build.yaml
文件,并结合此包嵌入不同的配置。构建时,可以通过 build_runner
的 --config
选项选择所需的环境。
目录
使用方法
1. 安装
embedded_config
依赖于 build_runner
包。为了避免将 build_runner
作为普通依赖项添加,embedded_config
提供了一个伙伴包 embedded_config_annotations
。
- 在
pubspec.yaml
中添加以下依赖项:
dependencies:
embedded_config_annotations: ^0.3.0
dev_dependencies:
embedded_config: ^0.4.0
build_runner: ^2.0.0
2. 创建嵌入式配置类
配置是通过生成一个扩展抽象“嵌入式配置”类的类来嵌入到应用程序中的。生成的扩展类包含来自配置源的硬编码配置值。
- 创建一个带有
@EmbeddedConfig
注解的抽象类:- 该类必须有一个默认的
const
构造函数。 - 可以在类中定义抽象 getter,这些 getter 将映射到配置源中的键。
- 该类必须有一个默认的
// file: app_config.dart
import 'package:embedded_config_annotations/embedded_config_annotations.dart';
// 添加生成的文件作为 part
part 'app_config.embedded.dart';
@EmbeddedConfig('app_config')
abstract class AppConfig {
// 获取 API URL
String get apiUrl;
// 获取 Auth 配置
AppAuthConfig get auth;
// 必须声明一个默认的 const 构造函数
const AppConfig();
}
// 由于这个类表示配置中的子对象,因此需要指定从配置根到该对象的路径
@EmbeddedConfig('app_config', path: ['auth'])
abstract class AppAuthConfig {
// 获取客户端 ID,值将从环境变量 AUTH_CLIENT_ID 中获取
String get clientId;
const AppAuthConfig();
}
- 暴露生成的类:
- 可以通过
static const
单例方式暴露生成的类。
- 可以通过
@EmbeddedConfig('app_config')
abstract class AppConfig {
static const AppConfig instance = _$AppConfigEmbedded();
String get apiUrl;
AppAuthConfig get auth;
const AppConfig();
}
3. 映射配置来源
接下来,我们需要实际的配置。配置可以指定在应用程序包中的配置文件或 build.yaml
文件中。有效的配置文件包括 JSON 和 YAML 格式的文件。
- 在
build.yaml
中配置embedded_config
:- 将配置源键(如
app_config
)映射到 JSON 或 YAML 文件。
- 将配置源键(如
targets:
$default:
builders:
embedded_config:
options:
# 将配置源键 'app_config' 映射到 'lib/app_config.json' 文件
app_config: 'lib/app_config.json'
- 配置文件示例:
- 假设
app_config.json
文件内容如下:
- 假设
{
"apiUrl": "/api",
"auth": {
"clientId": "$AUTH_CLIENT_ID"
}
}
- 生成的文件:
- 构建后,会生成一个名为
app_config.embedded.dart
的文件,其中包含硬编码的配置值。
- 构建后,会生成一个名为
part of 'app_config.dart';
class _$AppConfigEmbedded extends AppConfig {
const _$AppConfigEmbedded();
@override
final apiUrl = '/api';
@override
final auth = _$AppAuthConfigEmbedded();
}
class _$AppAuthConfigEmbedded extends AppAuthConfig {
const _$AppAuthConfigEmbedded();
@override
final clientId = 'your_client_id'; // 从环境变量 AUTH_CLIENT_ID 获取
}
合并配置
可以将多个配置源映射到同一个注解类。例如,可以定义一个基础的 app_config.json
文件和环境特定的 app_config.dev.json
和 app_config.prod.json
文件。在 build.dev.yaml
文件中,可以将 dev
JSON 文件映射到基础文件上,而在 build.prod.yaml
文件中映射 prod
文件。
targets:
$default:
builders:
embedded_config:
options:
app_config:
source:
- 'lib/app_config.json'
- 'lib/app_config.dev.json'
内联配置来源
配置也可以直接在 build.yaml
文件中指定。这可以通过 inline
属性完成。
targets:
$default:
builders:
embedded_config:
options:
app_config:
inline:
apiUrl: '/api2'
复杂配置模型
当配置不是扁平的键值对时,可以使用多个注解的嵌入式配置类。这通过设置 @EmbeddedConfig
注解的 path
属性来实现。path
是一个从配置根到所需子对象的配置键列表。
@EmbeddedConfig('app_config')
abstract class AppConfig {
String get prop1;
AppSubConfig get sub;
const AppConfig();
}
@EmbeddedConfig('app_config', path: ['sub'])
abstract class AppSubConfig {
String get prop2;
AppSub2Config get sub2;
const AppSubConfig();
}
@EmbeddedConfig('app_config', path: ['sub', 'sub2'])
abstract class AppSub2Config {
String get prop3;
const AppSub2Config();
}
环境变量
环境变量可以替换配置中的任何字符串值。这通过以 $
开头的值来实现。例如,$BUILD_ID
将被替换为环境变量 BUILD_ID
的值。
转义环境变量
如果配置值以 $
开头但不希望被替换为环境变量,可以使用 \
进行转义。
{
"value": "\$BUILD_ID"
}
示例:嵌入 CI 构建标识符
可以通过环境变量将 CI 构建标识符嵌入到应用程序中。
import 'package:embedded_config_annotations/embedded_config_annotations.dart';
@EmbeddedConfig('environment')
abstract class Environment {
String get buildId;
const Environment();
}
可以在 JSON 源中指定环境变量:
{
"buildId": "$BUILD_ID"
}
或者在 build.yaml
中内联指定:
targets:
$default:
builders:
embedded_config:
options:
environment:
inline:
buildId: '$BUILD_ID'
完整示例 Demo
假设我们有一个多级 JSON 配置文件 app_config.json
,并且希望将其嵌入到应用程序中,同时使用环境变量。
1. 配置文件 app_config.json
{
"apiUrl": "/api",
"auth": {
"clientId": "$AUTH_CLIENT_ID"
}
}
2. Dart 类 app_config.dart
// file: lib/app_config.dart
import 'package:embedded_config_annotations/embedded_config_annotations.dart';
part 'app_config.embedded.dart';
@EmbeddedConfig('app_config')
abstract class AppConfig {
static const AppConfig instance = _$AppConfigEmbedded();
String get apiUrl;
AppAuthConfig get auth;
const AppConfig();
}
@EmbeddedConfig('app_config', path: ['auth'])
abstract class AppAuthConfig {
String get clientId;
const AppAuthConfig();
}
3. build.yaml
配置
targets:
$default:
builders:
embedded_config:
options:
app_config: 'lib/app_config.json'
4. 使用配置
在应用程序中使用嵌入的配置:
void main() {
print('API URL: ${AppConfig.instance.apiUrl}');
print('Client ID: ${AppConfig.instance.auth.clientId}');
}
更多关于Flutter嵌入式配置插件embedded_config的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter嵌入式配置插件embedded_config的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用embedded_config
插件进行嵌入式配置的示例代码。这个插件通常用于从外部源(如服务器或本地文件)加载配置信息,并将其注入到Flutter应用中。
首先,你需要在你的pubspec.yaml
文件中添加embedded_config
依赖:
dependencies:
flutter:
sdk: flutter
embedded_config: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来获取依赖。
接下来,我们将编写一些代码来展示如何使用embedded_config
插件。
1. 配置数据模型
首先,定义一个配置数据的模型类。假设我们的配置包含API的基础URL和一些其他设置:
// config_model.dart
class ConfigModel {
final String apiBaseUrl;
final String theme;
ConfigModel({required this.apiBaseUrl, required this.theme});
factory ConfigModel.fromJson(Map<String, dynamic> json) {
return ConfigModel(
apiBaseUrl: json['apiBaseUrl'] as String,
theme: json['theme'] as String,
);
}
}
2. 加载配置
然后,我们编写一个方法来从外部源(例如,本地JSON文件或网络)加载配置,并使用embedded_config
插件将其注入到应用中。
这里以从本地JSON文件加载配置为例:
// main.dart
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:embedded_config/embedded_config.dart';
import 'config_model.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 假设你的配置文件名为config.json,位于assets文件夹下
final String configAssetPath = 'assets/config.json';
late ConfigModel configModel;
// 从assets文件夹加载配置
rootBundle.loadString(configAssetPath).then((String jsonString) async {
final Map<String, dynamic> jsonMap = jsonDecode(jsonString);
configModel = ConfigModel.fromJson(jsonMap);
// 使用embedded_config插件设置全局配置
await EmbeddedConfig.instance.set(key: 'config', value: configModel);
// 运行应用
runApp(MyApp());
}).catchError((error) {
print('Error loading config: $error');
// 可以在这里处理错误,例如显示错误消息或使用默认配置
configModel = ConfigModel(apiBaseUrl: 'https://default-api.com', theme: 'light');
EmbeddedConfig.instance.set(key: 'config', value: configModel);
runApp(MyApp());
});
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
// 从embedded_config获取配置
final ConfigModel? config = EmbeddedConfig.instance.get<ConfigModel>('config');
if (config != null) {
print('API Base URL: ${config.apiBaseUrl}');
print('Theme: ${config.theme}');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Text('Loading configuration...'),
),
);
}
}
3. 配置JSON文件
确保在assets
文件夹中有一个名为config.json
的文件,内容如下:
{
"apiBaseUrl": "https://api.example.com",
"theme": "dark"
}
并在pubspec.yaml
中添加对assets
文件夹的引用:
flutter:
assets:
- assets/config.json
4. 运行应用
现在,你可以运行你的Flutter应用,它将从config.json
文件中加载配置,并使用embedded_config
插件将其注入到应用中。
请注意,这只是一个基本示例。在实际应用中,你可能需要处理更多的错误情况,并从更复杂的源(如网络请求)加载配置。此外,embedded_config
插件的具体用法可能会根据其版本和文档有所不同,因此请参考最新的官方文档以获取最佳实践。