2011-12-02 36 views
13

¿Es posible asignar propiedades a instaladores privados usando AutoMapper?Propiedades de mapeo de AutoMapper con configuradores privados

+0

¿Qué versión de AutoMapper está usando? ¿Has intentado hacerlo? – PatrickSteele

+8

@blockhead en realidad es una pregunta muy importante, los objetos inmutables son una práctica arquitectónica mucho mejor que los objetos que se pueden cambiar a voluntad (al exponer a sus instaladores públicamente). Esta es la razón exacta por la que Entity Framework recientemente agregó la capacidad de hidratarse en propiedades privadas, para permitir que el modelo de dominio permanezca inmutable después de la hidratación inicial. Quizás no es leozilla lo que necesita mejorar su arquitectura. ;) – Marchy

+0

¿Disculpe? Se supone que las propiedades privadas son privadas. Son datos que pertenecen al objeto, y solo el objeto lo sabe, y deben saber sobre esos datos. – blockhead

Respuesta

15

Si se establece el valor de estas propiedades en el constructor como esto

public class RestrictedName 
{ 
    public RestrictedName(string name) 
    { 
     Name = name; 
    } 

    public string Name { get; private set; } 
} 

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

entonces puede utilizar ConstructUsing como esto

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

que trabaja con este código

var openName = new OpenName {Name = "a"}; 
var restrictedName = Mapper.Map<OpenName, RestrictedName>(openName); 
Assert.AreEqual(openName.Name, restrictedName.Name); 
+2

Esto no parece ser necesario con la última versión. Puedo mapear en clases con setters privados. Debe estar usando la reflexión internamente. – Monstieur

+0

@Locutus ¿Tal vez podrías convertir ese comentario en una respuesta? Probablemente debería marcarse como la nueva respuesta a esta pregunta. – julealgon

9

AutoMapper permite ahora (no estoy seguro, desde cuándo) mapear propiedades con entidades privadas. Está utilizando la reflexión para crear objetos.

clases Ejemplo:

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


public class PersonDto 
{ 
    public string Fullname { get; private set; } 
} 

y mapeo:

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 trazará un mapa de la propiedad privada con el colocador sin ningún problema. Si desea forzar la encapsulación, debe usar IgnoreAllPropertiesWithAnInaccessibleSetter. Con esta opción, se ignorarán todas las propiedades privadas (y otras inaccesibles).

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

El problema surgirá, si va a utilizar Silverlight. De acuerdo con 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. 
3

Ver #600 Private/internal destination properties.

Solución:

public class PrivateInternalProfile { 
    protected override Configure() { 
     ShouldMapField = fieldInfo => true; 
     ShouldMapProperty = propertyInfo => true; 
     CreateMap<User, UserDto>(); //etc 
    } 
} 
Cuestiones relacionadas