Я тестирую 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?