Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper with ValueFormatter

I'm learning how to use AutoMapper, and I'm having problems using it with ValueFormatter.

Here's simple example in Console, where I'm unable to use it with NameFormatter:

class Program
{
    static void Main(string[] args)
    {
        Mapper.Initialize(x => x.AddProfile<ExampleProfile>());

        var person = new Person {FirstName = "John", LastName = "Smith"};

        PersonView oV = Mapper.Map<Person, PersonView>(person);

        Console.WriteLine(oV.Name);

        Console.ReadLine();
    }
}

public class ExampleProfile : Profile
{
    protected override void Configure()
    {
        //works:
        //CreateMap<Person, PersonView>()
        //    .ForMember(personView => personView.Name, ex => ex.MapFrom(
        //        person => person.FirstName + " " + person.LastName));

        //doesn't work:
        CreateMap<Person, PersonView>()
            .ForMember(personView => personView.Name, 
             person => person.AddFormatter<NameFormatter>());
    }
}

public class NameFormatter : ValueFormatter<Person>
{
    protected override string FormatValueCore(Person value)
    {
        return value.FirstName + " " + value.LastName;
    }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class PersonView
{
    public string Name { get; set; }
}

What am I missing here? AutoMapper is version 2.2.1

like image 539
Janez Lukan Avatar asked Oct 04 '22 22:10

Janez Lukan


1 Answers

You should use a ValueResolver (some more infos here) :

public class PersonNameResolver : ValueResolver<Person, string>
{
    protected override string ResolveCore(Person value)
    {
        return (value == null ? string.Empty : value.FirstName + " " + value.LastName);
    }
}

and your profile should be something like this:

public class ExampleProfile : Profile
{
    protected override void Configure()
    {
        CreateMap<Person, PersonView>()
            .ForMember(personView => personView.Name, person => person.ResolveUsing<PersonNameResolver>());
    }
}

According to the author Formatters are for global type conversions. You can read some of his replies here and here.

I would go for the first of your options:

 CreateMap<Person, PersonView>()
      .ForMember(personView => personView.Name, ex => ex.MapFrom(
           person => person.FirstName + " " + person.LastName));

And apparently value formatters have been a mistake.

like image 82
LeftyX Avatar answered Oct 07 '22 20:10

LeftyX