一个用于从支持多种环境的 json 文件创建配置文件类的生成器。
动机
如果您使用 json 文件来配置您的应用程序,您可能需要编写一个包含所有已定义变量及其数据类型的 dart 类。当您需要管理嵌套对象时,会更复杂。即使您想在 json 中添加或删除一个值,您也需要修改您的 dart 类。
如果您想管理环境,您需要手动为所需的每个环境编写文件路径。
json_config_generator 旨在帮助您简化配置文件和环境的管理过程。
安装
要使用 json_config_generator,您需要 build_runner/代码生成器的设置。
首先,通过将它们添加到您的 pubspec.yaml 文件中来安装 build_runner 和 json_config_generator。
pubspec.yaml
dependencies:
json_config_annotation: ^0.1.0
dev_dependencies:
build_runner:
json_config_generator: ^0.1.0
- build_runner,运行代码生成器的工具
- json_config_generator,代码生成器
- json_config_annotation,一个包含 json_config_generator 注释的包
如何使用
要使用此生成器,您需要创建一个以 $ 开头的空配置文件类,并使用 Configuration 注释定义您想要的环境。每个环境都有 name 和 path,如果有多个环境,生成器会创建一个 Enum 来表示环境。您还可以指定该 Enum 的名称。默认名称是 Environment。此外,您还需要添加一些导入。
config.dart
import 'package:json_config_annotation/json_config_annotation.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
part 'config.g.dart'; //{dart file name}.g.dart
@Configuration(
environmentEnumName: 'Env',
environments:[
Environment(name:'dev', path:'assets/config/dev.json'),
Environment(name:'prd', path:'assets/config/prd.json'),
],
)
class $Config{}
假设有以下 json 文件
dev.json
{
"base_url": "https://example.com",
"custom_class": {
"value_1": "dfgdfgdfgwqrrqwrqwrqweqwe324523b252dghfdhd",
"value_2": "6Lez7aIaAAAAAN6qZG2343c252bv66b7yn5m8m6"
},
"int_value": 3,
"double_value": 3.5,
"boolean_value": true,
"string_list": ["hello", "world"],
"int_list": [1, 23, 5],
"bool_list": [false, true, true],
"custom_list": [
{
"value_1": "hello"
},
{
"value_1": "world"
}
]
}
生成器会创建
config.g.dart
enum Env { dev, prd }
class Config {
Config._();
static final instance = Config._();
late String baseUrl;
late _CustomClass customClass;
late int intValue;
late double doubleValue;
late bool booleanValue;
late List<String> stringList;
late List<int> intList;
late List<bool> boolList;
late List<_CustomList> customList;
Future<void> init(Env env) async {
String path = '';
switch (env) {
case Env.dev:
path = 'assets/config/dev.json';
break;
case Env.prd:
path = 'assets/config/prd.json';
break;
}
final jsonString = await rootBundle.loadString(path);
final config = json.decode(jsonString) as Map<String, dynamic>;
baseUrl = config['base_url'] as String;
customClass =
_CustomClass.fromJson(config['custom_class'] as Map<String, dynamic>);
intValue = config['int_value'] as int;
doubleValue = config['double_value'] as double;
booleanValue = config['boolean_value'] as bool;
stringList = (config['string_list'] as List).cast<String>();
intList = (config['int_list'] as List).cast<int>();
boolList = (config['bool_list'] as List).cast<bool>();
customList = _CustomList.listFromJson(config['custom_list'] as List);
}
}
class _CustomClass {
const _CustomClass({required this.value1, required this.value2});
factory _CustomClass.fromJson(Map<String, dynamic> customClass) =>
_CustomClass(
value1: customClass['value_1'] as String,
value2: customClass['value_2'] as String,
);
final String value1;
final String value2;
}
class _CustomList {
const _CustomList({required this.value1});
factory _CustomList.fromJson(Map<String, dynamic> customList) => _CustomList(
value1: customList['value_1'] as String,
);
final String value1;
static List<_CustomList> listFromJson(List data) =>
data.map((e) => _CustomList.fromJson(e as Map<String, dynamic>)).toList();
}
要使用生成的配置,您需要调用 init 方法来初始化所有值。可以在 main 中调用它,并指定要使用的环境。
main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Config.instance.init(Env.dev);
runApp(const MyApp());
}
现在可以通过 instance 轻松访问字段
Config.instance.baseUrl;
Config.instance.customClass.value1;
支持的数据类型
- String
- int
- double
- bool
- CustomClass
- List<String>
- List<int>
- List<double>
- List<bool>
- List<CustomClass>
也可以创建嵌套类!
重要提示
- 不支持可空值
- 不支持动态值
运行生成器
要运行生成器,请使用以下命令之一
flutter pub run build_runner builddart pub run build_runner build
注意事项
也可以创建一个只有一种 Environment 的配置。如果是这样,则不会创建 Enum,调用 init 方法时也不需要传递任何参数。
重要的是要知道生成器会取列表中的第一个值来确定列表的类型,所以要小心。