Dart 对象映射库发布!

1,920 阅读2分钟

在应用程序中,通常会有一些相似,但是又不同的对象模型,其中两个模型中的数据可能相似,但是模型的结构和关注点不同。通过对象映射,可以十分方便的将一个模型转换为另一个模型,从而使得分离的模型保持隔离的状态。

依赖库

model_mapper https://pub.dev/packages/model_mapper

前言

众所周知,虽然 Dart 支持反射,但是 Flutter 禁用了 Dart 的反射能力,所以像 Java 中一些需要用反射来实现的骚操作就不能用了。于是经过短暂的思考,决定用序列化和反序列化来实现对象映射。

我承认我有偷懒的成分,本该自己完成序列化代码的,但是因为时间问题,我在 json_serializable 的基础上实现了对象映射。这样虽然开发方便了,但是使用起来稍微麻烦了一些。

后面我会逐渐补上序列化部分的代码。如果哪位同学有兴趣,也可以来 Github 一起创作。

安装

将下面的依赖添加到你的 pubspec.yaml 中:

dependencies:
  model_mapper: ^0.0.1
  
dev_dependencies:
  build_runner: ^1.10.3
  json_serializable: ^4.0.0
  model_mapper_generator: ^0.1.0

用法

model_mapper 是在 json_serializable 的基础上运行的,所以第一步应该先配置json_serializable

  1. 按照 json_serializable 的要求配置你的 Model:

    import 'package:json_annotation/json_annotation.dart';
    
    part 'demo.g.dart';
    
    @JsonSerializable()
    class Demo1 {
      final String a;
      final String b;
    
      Demo1(this.b, {required this.a});
    
      factory Demo1.fromJson(Map<String, dynamic> json) => _$Demo1FromJson(json);
    
      Map<String, dynamic> toJson() => _$Demo1ToJson(this);
    }
    
    @JsonSerializable()
    class Demo2 {
      final String a;
      final String b;
    
      Demo2(this.a, this.b);
    
      factory Demo2.fromJson(Map<String, dynamic> json) => _$Demo2FromJson(json);
    
      Map<String, dynamic> toJson() => _$Demo2ToJson(this);
    
      @override
      String toString() {
        return "Demo2 { a: $a, b: $b }";
      }
    }
    
  2. 创建你的 ModelMapper,并使用 ModelMapperFor 添加你希望互相映射的所有 Model

    import 'package:model_mapper/model_mapper.dart';
    
    part 'demo_mapper.g.dart';
    
    @ModelMapperFor([Demo1, Demo2])
    abstract class DemoMapper extends ModelMapper {
    }
    
  3. 执行代码生成命令

    如果你是 Flutter 项目可以执行 flutter packages pub run build_runner build

    如果是 Dart 项目,请执行 dart pub run build_runner build

    build 换成 watch 可以在文件变化后自动执行: pub run build_runner watch

  4. 现在可以直接使用了。需要注意的是,实际调用的 ModelMapper 的类名是在你定义的 ModelMapper 类名前加一个 $,比如你定义的是 DemoMapper ,那你应该调用 $DemoMapper

    var demo1 = Demo1("b", a: "a");
    
    var demo2 = $DemoMapper.instance().map(demo1, Demo2);
    print(demo2);
    // output: Demo2: { a: a, b: b }
    

最后

Github 地址:github.com/T-Oner/mode…