Reputation: 5074
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
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