config_manager 0.2.0
config_manager: ^0.2.0 copied to clipboard
A JSON-based configuration manager with dot-notation access to nested values, singleton pattern, and mixin support.
example/main.dart
import 'package:config_manager/config_manager.dart';
class AppService with ConfigExtension {
void printInfo() {
print('--- Via ConfigExtension mixin ---');
print('appName: ${get('appName')}');
print('db host: ${get('database.host')}');
print('db user: ${get('database.credentials.user')}');
print('first feature: ${get('features.0')}');
final servers = get('servers') as List? ?? [];
for (final server in servers) {
print('server via mixin: ${server['name']} (${server['region']})');
}
}
}
/// A custom [IConfigExtension] backed by an in-memory map instead of the
/// singleton. Only `get(key, {sector})` needs implementing; it is inherited
/// from [IConfigBase].
class InMemoryConfig implements IConfigExtension {
final Map<String, dynamic> _store = {};
@override
dynamic get(String key, {String sector = kDefaultSector}) => _store[key];
@override
void loadFromMap(Map<String, dynamic> map, {String sector = kDefaultSector}) {
_store
..clear()
..addAll(map);
}
@override
void loadFromJson(String path, {String sector = kDefaultSector}) {}
@override
void loadFromString(String json, {String sector = kDefaultSector}) {}
}
void main() {
final config = ConfigManagerSingleton();
config.loadFromJson('example/config.json');
print('--- Via ConfigManagerSingleton ---');
print('appName: ${config.get('appName')}');
print('db port: ${config.get('database.port')}');
print('db user: ${config['database.credentials.user']}');
print('--- Lists via casting ---');
final features =
(config.get('features') as List?)?.cast<String>() ?? [];
print('features: $features');
print('feature count: ${features.length}');
for (final feature in features) {
print('feature: $feature');
}
final servers = config.get('servers') as List? ?? [];
for (final server in servers) {
final map = server as Map<String, dynamic>;
print('server: ${map['name']} -> ${map['region']}');
}
config.set('ports', [8080, 8081, 8082]);
final ports = (config.get('ports') as List?)?.cast<int>() ?? [];
print('ports: $ports');
config.set('database.replicas', ['replica-1', 'replica-2']);
print('nested list: ${config.get('database.replicas')}');
print('--- Lists + dot notation ---');
print('second feature: ${config.get('features.1')}');
print('first server name: ${config.get('servers.0.name')}');
print('second server region: ${config.get('servers.1.region')}');
print('first replica: ${config.get('database.replicas.0')}');
print('--- Writes and edge cases ---');
config.set('database.credentials.password', 's3cret');
print('written nested value: ${config.get('database.credentials.password')}');
print('missing key: ${config.get('does.not.exist')}');
print('index out of range: ${config.get('features.99')}');
print('missing list: ${config.get('noSuchList') as List? ?? []}');
print('--- Sectors ---');
// Each sector loads its own file; when no sector is passed the
// default sector is used.
config.loadFromJson('example/config.json', sector: 'sales');
print('loaded sectors: ${config.sectors.toList()}');
print('sales appName: ${config.get('appName', sector: 'sales')}');
print('default appName: ${config.get('appName')}');
config.set('region', 'eu-west', sector: 'sales');
print('sales region: ${config.get('region', sector: 'sales')}');
AppService().printInfo();
print('--- Via a custom IConfigExtension ---');
final IConfigExtension custom = InMemoryConfig()
..loadFromMap({'appName': 'in-memory', 'level': 3});
print('custom appName: ${custom.get('appName')}');
print('custom level: ${custom.get('level')}');
}