Dart

Mapr

This is a code gen / helper mapping package inspired by C#'s AutoMapper that makes it easier to map between objects by generating mapping methods that are exposed by a simple api.


Features:

  • Code generation of mapping classes
  • Auto mapping with field renaming and field recasing
  • A simple mapping api inspired by AutoMapper used by c# developers

Install

https://pub.dev/packages/mapr

add to your pubspec.yaml

dependencies:
    mapr: ^0.2.0

or run

dart pub add mapr or flutter pub add mapr


How to use

1. Have objects you want to map

class HouseAddress {
    final int houseNumber;
    final String streetName;

    const HouseAddress({
        required this.houseNumber,
        required this.streetName,
    });

    @override
    String toString() => '$houseNumber $streetName';
}

class BuildingAddress {
    final int BuildingNumber;
    final String StreetName;

    const BuildingAddress({
        required this.BuildingNumber,
        required this.StreetName,
    });

    @override
    String toString() => '$BuildingNumber $StreetName';
}

2. Setup mapper class

Setup @MaprBase annotation and then run

@MaprBase(objectMaps: [
    ObjectMap<HouseAddress, BuildingAddress>(
        fieldRename: {
            "houseNumber": "BuildingNumber",
        },
        srcConvention: NameConvention.camelCase,
        dstConvention: NameConvention.PascalCase,
    )
])
class Mapper extends $Mapper {
    @override
    configure() {
        // no additional maps needed since all should be auto generated
    }
}

3. Run build_runner

$ dart run build_runner build --delete-conflicting-outputs

4. Map objects!

void main() {
    final mapper = Mapper();

    final houseAddress = HouseAddress(
        houseNumber: 124,
        streetName: 'Conch St.',
    );
    print(houseAddress); // -> 124 Conch St.

    final buildingAddress = mapper.map<HouseAddress, BuildingAddress>(houseAddress);
    print(buildingAddress); // -> 124 Conch St.

    final origional = mapper.map<BuildingAddress, HouseAddress>(buildingAddress);
    print(origional); // -> 124 Conch St.
}

Setup map overrides

Sometimes fields do not map 1 to 1, in this case we can setup a map override for a single field or the entire class!

Individual fields override

class Person {
    String name;
    Address address; // Address(int houseNum, String streetName)
    const Person(this.name, this.address);
}

class DtoPerson {
    String Name;
    int HouseNumber;
    String StreetName;
    const DtoPerson(
        this.Name,
        this.HouseNumber,
        this.StreetName,
    );
}

@MaprBase(objectMaps: [
    ObjectMap<Person, DtoPerson>(
        srcConvention: NameConvention.camelCase,
        dstConvention: NameConvention.PascalCase,
    ),
])
class Mapper extends $Mapper {
    @override
    void configure() {
        setMap.so.Person.to.DtoPerson
            ..StreetName = ((source) => source.address.streetName)
            ..HouseNumber = ((source) => source.address.houseNum);

        setMap.so.PersonDto.to.Person.address
            = (source) => Address(source.HouseNumber, source.StreetName);

    }

}

Full override

    @override
    void configure() {
        setMap.so.Person.to.DtoPerson.customMap = (source) {
            return Person(
                source.Name,
                Address(source.HouseNumber, source.StreetName),
            );
        };
    }

Libraries

generators
mapr
Mapr is a library for auto generating and registering mapping models for dart objects This project was created in order to help separate the concerns of data objects inside dart and flutter projects. By removing mapping logic from the repository layer we can isolate mapping errors to a single place as well as test front end objects and backend objects separately