2016-11-10 4 views
0

Я тестирую automapper, чтобы узнать, может ли он делать то, что мне нужно в другом проекте, поэтому я сделал некоторые объекты в консольном проекте, упрощенном, но что должно быть то, что мне нужно:Как сопоставить объект с пользовательским конструктором из динамического объекта с помощью automapper

public class Person 
{ 
    public Person(List<Banco> bancos) 
    { 
     this._Bancos = bancos; 
    } 

    public int Id { get; set; } 
    public string Nombre { get; set; } 
    public DNI Dni { get; set; } 
    private List<Banco> _Bancos; 

    public List<Banco> Bancos 
    { 
     get { return _Bancos; } 
    } 

} 

public class DNI 
{ 
    private DNI() { } 
    public DNI(DNI2 letra) 
    { 
     this._Letra = letra; 
     Console.WriteLine("****DNI CONSTRUCTOR****"); 
    } 

    public int Id { get; set; } 
    public int PersonId { get; set; } 
    public string number { get; set; } 
    private DNI2 _Letra; 

    public DNI2 Letra 
    { 
     get { return _Letra; } 
    } 

} 

public class DNI2 
{ 
    public int Id { get; set; } 
    public int DNIId { get; set; } 
    public string letra { get; set; } 
} 

public class Banco 
{ 
    public int Id { get; set; } 
    public string number { get; set; } 
} 

Как вы можете видеть, объекты Person и DNI имеют собственный cosntructor, и я выставиться один последний в конструктор без параметров по умолчанию конфиденциальный.

Теперь мне нужно отобразить вложенные объекты с пользовательскими конструкторами из динамических объектов, так что я сделал это в том же проекте консоли:

class Program 
{ 
    static void Main(string[] args) 
    { 
     //OJO TODO: ¿Si un objeto dinamico tiene propiedades de varios tipos, es capaz de diferenciar a qué tipo pertenece cada prop? 
     //¿qué pasa si un valor del dinamico es del tipo equivocado? 
     var bancoConfig = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true); 
     var DNI2Config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true); 
     DNI2Config.AssertConfigurationIsValid(); 
     var bancoMapper = bancoConfig.CreateMapper(); 
     var dni2Mapper = DNI2Config.CreateMapper(); 

     var dni2DBConfig = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMissingTypeMaps = true; 
      cfg.RecognizePrefixes("DNI2"); 
     }); 
     var dni2DBMapper = dni2DBConfig.CreateMapper(); 

     var DNIConfig = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<dynamic, DNI>() 
      .ConstructUsing(dyn => new DNI(dni2DBMapper.Map<DNI2>(dyn))); 
      /*.ForMember(dest => dest.Id, opts => opts.MapFrom<int>(src => (int)(src as IDictionary<string, object>)["Id"])) 
      .ForMember(dest => dest.number, opts => opts.MapFrom<string>(src => (string)(src as IDictionary<string, object>)["number"])) 
      .ForMember(dest => dest.PersonId, opts => opts.MapFrom<int>(src => (int)(src as IDictionary<string, object>)["PersonId"]));*/ 
      /*cfg.CreateMap<IDictionary<string, object>, DNI>() 
      .ConstructUsing(dyn => new DNI(dni2DBMapper.Map<DNI2>(dyn as dynamic))) 
      .ForMember(dest => dest.Id, opts => opts.MapFrom<int>(src => (int)(src["Id"]))) 
      .ForMember(dest => dest.number, opts => opts.MapFrom<string>(src => (string)(src["number"]))) 
      .ForMember(dest => dest.PersonId, opts => opts.MapFrom<int>(src => (int)(src["PersonId"])));*/ 

      cfg.CreateMissingTypeMaps = true; 
     }); 
     var dniMapper = DNIConfig.CreateMapper(); 

     dynamic d = new { Id = 0, number = "1234" }; 
     Banco banco = bancoMapper.Map<Banco>(d); 
     Console.WriteLine("Banco: " + Environment.NewLine); 
     Console.WriteLine(banco.Id + Environment.NewLine + banco.number); 
     Console.ReadLine(); 

     d = new { Id = 1, DNIId = 0, letra = "a" }; 
     DNI2 dni2 = dni2Mapper.Map<DNI2>(d); 
     Console.WriteLine("DNI2: " + Environment.NewLine); 
     Console.WriteLine(dni2.Id + Environment.NewLine + dni2.DNIId + Environment.NewLine + dni2.letra); 
     Console.ReadLine(); 

     d = new { Id = 2, PersonId = 5, number = "5678", DNI2Id = 2, DNIId = 2, letra = "b" }; 
     DNI2 d2 = dni2DBMapper.Map<DNI2>(d); 
     DNI dni = dniMapper.Map<DNI>(d); 
     Console.WriteLine("DNI: " + Environment.NewLine); 
     Console.WriteLine(dni.Id + Environment.NewLine + dni.PersonId + Environment.NewLine + dni.number + Environment.NewLine); 
     Console.WriteLine("dni.dni2: "+dni.Letra.Id + Environment.NewLine + dni.Letra.DNIId + Environment.NewLine + dni.Letra.letra); 
     Console.ReadLine(); 
    } 
} 

Это дает этот результат в консоли:

Banco: 

0 
1234 

DNI2: 

1 
0 
a 

****DNI CONSTRUCTOR**** 
DNI: 

2 
5 
5678 

dni.dni2: 0 
0 

Итак, он просто создает объект DNI и устанавливает члены, он проходит через открытый конструктор ... но даже когда он проходит через конструктор, он не устанавливает свойство DNI2.
Если я Coment динамической линии в конфигурации DNI:

 var DNIConfig = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<dynamic, DNI>() 
      .ConstructUsing(dyn => new DNI(dni2DBMapper.Map<DNI2>(dyn))); 
      /*.ForMember(dest => dest.Id, opts => opts.MapFrom<int>(src => (int)(src as IDictionary<string, object>)["Id"])) 
      .ForMember(dest => dest.number, opts => opts.MapFrom<string>(src => (string)(src as IDictionary<string, object>)["number"])) 
      .ForMember(dest => dest.PersonId, opts => opts.MapFrom<int>(src => (int)(src as IDictionary<string, object>)["PersonId"]));*/ 
      /*cfg.CreateMap<IDictionary<string, object>, DNI>() 
      .ConstructUsing(dyn => new DNI(dni2DBMapper.Map<DNI2>(dyn as dynamic))) 
      .ForMember(dest => dest.Id, opts => opts.MapFrom<int>(src => (int)(src["Id"]))) 
      .ForMember(dest => dest.number, opts => opts.MapFrom<string>(src => (string)(src["number"]))) 
      .ForMember(dest => dest.PersonId, opts => opts.MapFrom<int>(src => (int)(src["PersonId"])));*/ 

      //cfg.CreateMissingTypeMaps = true; 
     }); 

... так что это не имеют конфигураций, чтобы сделать его динамичным, результат:

Banco: 

0 
1234 

DNI2: 

1 
0 
a 

****DNI CONSTRUCTOR**** 
DNI: 

0 
0 


dni.dni2: 2 
2 
b 

комментируемой линия в конфигурация является лишь частью того, что я пробовал, в том числе двухдневный поиск здесь и google.
Кажется, что программа говорит мне: вы сопоставляете ее с динамическим или, вы используете пользовательский конструктор, вы не можете обойтись и сосать его.

Наиболее интригующая часть для меня: с использованием первой конфигурации она не отображает объект DNI2, но он сопоставляет объект DNI с использованием конструктора (строка находится на консоли), но это не есть объект, необходимый параметрам, поэтому он использует конструктор без нужного параметра O_o ​​
Честно говоря, я знаю, что я любитель и все, но я всегда думал, что даже используя отражение, вы не могли бы использовать конструктор (ни один другой метод) без каких-либо требуемых параметров.

So: Есть ли способ сопоставить вложенный объект с пользовательским конструктором из динамического объекта с помощью automapper?

ответ

0

Я нашел решение этой:

 var DNIDynConfig = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true); 
     var dniDynMapper = DNIDynConfig.CreateMapper(); 
     var DNIConfig = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<dynamic, DNI>() 
      .ConstructUsing(dyn => new DNI(dni2DBMapper.Map<DNI2>(dyn))) 
      .AfterMap((src, dest) => 
      { 
       dniDynMapper.Map(src, dest, typeof(object), typeof(DNI)); 
      }); 
     }); 

мне не очень нравится, так как кажется, что он должен отобразить объект в два раза, но это работает. Если бы кто-то пришел с чем-то лучше, я бы понесся.