Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper mapping properties with private setters

Is it possible to assign properties with private setters using AutoMapper?

like image 479
leozilla Avatar asked Dec 02 '11 10:12

leozilla


People also ask

Does AutoMapper map private properties?

By default, AutoMapper only recognizes public members. It can map to private setters, but will skip internal/private methods and properties if the entire property is private/internal.

How do I use AutoMapper to list a map?

How do I use AutoMapper? First, you need both a source and destination type to work with. The destination type's design can be influenced by the layer in which it lives, but AutoMapper works best as long as the names of the members match up to the source type's members.

Can AutoMapper map collections?

Polymorphic element types in collectionsAutoMapper supports polymorphic arrays and collections, such that derived source/destination types are used if found.

How do I ignore source property AutoMapper?

So, the AutoMapper Ignore() method is used when you want to completely ignore the property in the mapping. The ignored property could be in either the source or the destination object.


2 Answers

AutoMapper allows now (I am not sure, since when) to map properties with private setters. It is using reflection for creating objects.

Example classes:

public class Person {     public string Name { get; set; }     public string Surname { get; set; } }   public class PersonDto {     public string Fullname { get; private set; } } 

And mapping:

AutoMapper.Mapper.CreateMap<Person, PersonDto>()     .ForMember(dest => dest.Fullname, conf => conf.MapFrom(src => src.Name + " " + src.Surname));  var p = new Person() {     Name = "John",     Surname = "Doe" };  var pDto = AutoMapper.Mapper.Map<PersonDto>(p); 

AutoMapper will map property with private setter with no problem. If you want to force encapsulation, you need to use IgnoreAllPropertiesWithAnInaccessibleSetter. With this option, all private properties (and other inaccessible) will be ignored.

AutoMapper.Mapper.CreateMap<Person, PersonDto>()     .ForMember(dest => dest.Fullname, conf => conf.MapFrom(src => src.Name + " " + src.Surname))     .IgnoreAllPropertiesWithAnInaccessibleSetter(); 

The problem will emerge, if you will use Silverlight. According to MSDN: https://msdn.microsoft.com/en-us/library/stfy7tfc(v=VS.95).aspx

In Silverlight, you cannot use reflection to access private types and members.

like image 173
Rafał Straszewski Avatar answered Sep 24 '22 22:09

Rafał Straszewski


If you set the value for this properties in the constructor like this

public class RestrictedName {     public RestrictedName(string name)     {         Name = name;     }      public string Name { get; private set; } }  public class OpenName {     public string Name { get; set; } } 

then you can use ConstructUsing like this

Mapper.CreateMap<OpenName, RestrictedName>()             .ConstructUsing(s => new RestrictedName(s.Name)); 

which works with this code

var openName = new OpenName {Name = "a"}; var restrictedName = Mapper.Map<OpenName, RestrictedName>(openName); Assert.AreEqual(openName.Name, restrictedName.Name); 
like image 36
boca Avatar answered Sep 22 '22 22:09

boca