3dGrabber
3dGrabber

Reputation: 5074

Class based Converter for Object-to-Object Mapper

I am looking for a Object-to-Object mapper that can do the following:

Given:

class Source
{
    string   FirstName;
    string   LastName;
    DateTime DateOfBirth;
}

and

class Target
{
    string FirstName;
    string FamilyName;
    string FullName;
    int    Age;
    bool   IsMinor;
}

Source and Target being untouchable 3rd party code.

I would like to be able to provide a convention (name-) based converter class like this:

class Converter
{
    // field
    public DateTime CurrentDate;  

    // map LastName to FamilyName
    string FamilyName(string lastName) => lastName;

    // map FirstName & LastName to FullName
    string FullName(string firstName, string lastName) => firstName + " " + lastName;

    // map DateOfBirth to Age
    int Age(DateTime dateOfBirth)  
    {
        var days = (CurrentDate - dateOfBirth).TotalDays;
        return (int)(days / 365.25);
    }

    // map DateOfBirth to IsMinor
    bool IsMinor(DateTime dateOfBirth) => Age(dateOfBirth) < 18;  

    // Note: implicit map from FirstName to FirstName     
}

And then be able to use it like this:

var converter = new Converter {CurrentDate = DateTime.Now};
var mapper    = new Mapper<Source,Target>(converter);  // any mapping lib available for this? 
var targetObject = mapper.Convert(sourceObject);

Is there any .Net mapping library around that can do this?
If yes, can someone give an example how to do it?

Upvotes: 0

Views: 221

Answers (1)

OrdinaryOrange
OrdinaryOrange

Reputation: 2712

Here is one way to do it with Automapper. It just uses the static initialiser so the mapping is application wide, and obviously one would implement a better age algorithm...Oh an the Source and Target classes need public properties.

Func<DateTime, int> AgeFunc = (dob) => (int)(DateTime.Now - dob).TotalDays/365;
Mapper.Initialize(cfg =>

    cfg.CreateMap<Source, Target>()
        .ForMember(dest => dest.FamilyName ,m => m.MapFrom(src => src.LastName))
        .ForMember(dest => dest.FullName, m => m.MapFrom(src => src.FirstName + " "  + src.LastName))
        .ForMember(dest => dest.Age, m => m.MapFrom(src => AgeFunc(src.DateOfBirth)))
        .ForMember(dest => dest.IsMinor, m => m.MapFrom(src => AgeFunc(src.DateOfBirth) < 18 ))
);

var peter = new Source() {FirstName = "Peter", LastName="Pan", DateOfBirth=DateTime.Now.AddDays(-7) };
var captain = new Source() {FirstName = "Captain", LastName="Hook", DateOfBirth=DateTime.Now.AddDays(-20000) };

var targetPerter = Mapper.Map<Target>(peter);
var targetCaptain = Mapper.Map<Target>(captain);

Upvotes: 1

Related Questions