简体   繁体   中英

How to tell AutoMapper to use "pass by reference?"

By default automapper creates a new object based on the destination's type:

public void Doit( Person personMissingStuff )
{
    PersonTemplate template = _personDao.GetPersonTemplate(1);
    Mapper.CreateMap<PersonTemplate, Person>();
    Person basePerson = Mapper.Map<Person>( template );
    Mapper.CreateMap<Person, Person>();
    Person completePerson = 
       Mapper.Map<Person, Person>( basePerson, personMissingStuff );
    ...
}

Instead of getting a completePerson I just get a basePerson again. How do I tell AutoMapper to run the mappings by reference instead of by value?

Mapper.Map(source, dest) actually returns the destination object, in your case it'll be personMissingStuff .

With that said, assuming that you want to fill in only the null properties in the destination, you need to configure the mapping properly, and not map when the destination property has value.

The following sample does exactly this for class properties. For value properties, probably you need to do additional configuration. The example uses NUnit and SharpTestsEx:

[TestFixture]
public class LoadIntoInstance
{
    public class Template
    {
        public string Name { get; set; }
    }

    public class Person
    {
        public string Name { get; set; }
        public string OtherData { get; set; }
    }        

    [Test]
    public void Should_load_into_instance()
    {
        Mapper.CreateMap<Template, Person>()
            .ForMember(d=>d.OtherData, opt=>opt.Ignore());
        Mapper.CreateMap<Person, Person>()
            .ForAllMembers(opt=>opt.Condition(ctx=>ctx.DestinationValue==null));
        Mapper.AssertConfigurationIsValid();

        var template = new Template {Name = "template"};
        var basePerson = Mapper.Map<Person>(template);

        var noNamePerson = new Person {OtherData = "other"};

        var result = Mapper.Map(basePerson, noNamePerson);

        result.Should().Be.SameInstanceAs(noNamePerson);
        result.Satisfy(r =>
                       r.Name == "template" &&
                       r.OtherData == "other");
    }
}

Just use traditional shallow cloning...

Person completePerson = basePerson.MemberwiseClone();

This should keep the reference types and clone the value types.

MSDN Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM