Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper - What's difference between Condition and PreCondition

Tags:

c#

automapper

Suppose a mapping using AutoMapper like bellow:

mapItem.ForMember(to => to.SomeProperty, from =>
{
    from.Condition(x => ((FromType)x.SourceValue).OtherProperty == "something");
    from.MapFrom(x => x.MyProperty);
});

What's difference of substitute Condition by PreCondition:

    from.PreCondition(x => ((FromType)x.SourceValue).OtherProperty == "something");

What's the practical difference between this two methods?

like image 472
Gean Ribeiro Avatar asked Nov 17 '16 15:11

Gean Ribeiro


People also ask

What is conditional mapping?

Conditional Field Mapping allows you to control whether or not a value or field is written to a target datastore based on the contents of the source data. For example, if there is a NULL value in a source field, you can choose to overwrite target data with the NULL value or skip that field when updating a record.

When should I use AutoMapper?

AutoMapper is used whenever there are many data properties for objects, and we need to map them between the object of source class to the object of destination class, Along with the knowledge of data structure and algorithms, a developer is required to have excellent development skills as well.

What is the use of AutoMapper in C#?

AutoMapper is a popular object-to-object mapping library that can be used to map objects belonging to dissimilar types. As an example, you might need to map the DTOs (Data Transfer Objects) in your application to the model objects.


1 Answers

The diference is that PreCondition is executed before acessing the source value and also the Condition predicate, so in this case, before get the value from MyProperty the PreCondition predicate will run, and then the value from property is evaluated and finally Condition is executed.

In the following code you can see this

class Program
{
    static void Main(string[] args)
    {
        Mapper.Initialize(cfg =>
        {
            cfg.CreateMap<Person, PersonViewModel>()
                .ForMember(p => p.Name, c =>
                {
                    c.Condition(new Func<Person, bool>(person =>
                    {
                        Console.WriteLine("Condition");
                        return true;
                    }));
                    c.PreCondition(new Func<Person, bool>(person =>
                    {
                        Console.WriteLine("PreCondition");
                        return true;
                    }));
                    c.MapFrom(p => p.Name);
                });
        });

        Mapper.Instance.Map<PersonViewModel>(new Person() { Name = "Alberto" });
    }
}

class Person
{
    public long Id { get; set; }
    private string _name;

    public string Name
    {
        get
        {
            Console.WriteLine("Getting value");
            return _name;
        }
        set { _name = value; }
    }
}

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

The output from this program is:

PreCondition
Getting value
Condition

Because the Condition method contains a overload that receives a ResolutionContext instance, that have a property called SourceValue, the Condition evaluate the property value from source, to set the SourceValue property on ResolutionContext object.

ATTENTION:

This behavior work properly until version <= 4.2.1 and >= 5.2.0.

The versions between 5.1.1 and 5.0.2, the behavior is not working properly anymore.

The output in those versions is:

Condition
PreCondition
Getting value
like image 134
Alberto Monteiro Avatar answered Sep 18 '22 05:09

Alberto Monteiro