c# - How to map an object with a custom constructor from a dynamic object with automapper -
i'm testing automapper see if can need in other project, i've made objects in console project, simplified should have need:
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 { { 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 { { 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; } }
as can see, objects person
, dni
have custom cosntructor, , setted last one's default parameterless constructor private.
now, need map nested objects custom constructors dynamic objects, made in same console project:
class program { static void main(string[] args) { //ojo todo: ¿si un objeto dinamico tiene propiedades de varios tipos, es capaz de diferenciar 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 idictionary<string, object>)["id"])) .formember(dest => dest.number, opts => opts.mapfrom<string>(src => (string)(src idictionary<string, object>)["number"])) .formember(dest => dest.personid, opts => opts.mapfrom<int>(src => (int)(src idictionary<string, object>)["personid"]));*/ /*cfg.createmap<idictionary<string, object>, dni>() .constructusing(dyn => new dni(dni2dbmapper.map<dni2>(dyn 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(); } }
that gives result in console:
banco: 0 1234 dni2: 1 0 ****dni constructor**** dni: 2 5 5678 dni.dni2: 0 0
so, creates dni
object , set members, go through public constructor... when goes through constructor doesn't set dni2
property.
if coment dynamic line in dni
configuration:
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 idictionary<string, object>)["id"])) .formember(dest => dest.number, opts => opts.mapfrom<string>(src => (string)(src idictionary<string, object>)["number"])) .formember(dest => dest.personid, opts => opts.mapfrom<int>(src => (int)(src idictionary<string, object>)["personid"]));*/ /*cfg.createmap<idictionary<string, object>, dni>() .constructusing(dyn => new dni(dni2dbmapper.map<dni2>(dyn 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; });
... not have config make dynamic, result is:
banco: 0 1234 dni2: 1 0 ****dni constructor**** dni: 0 0 dni.dni2: 2 2 b
the commented lines in configuration part of i've tried, including 2 days searching here , google.
seems program telling me: map dynamic or use custom constructor, can not both, suck it.
the intriguing part me is: using first configuration, isn't mapping dni2
object, mapping dni
object using constructor(the line @ console), don't have object needed parameters, using constructor without required parameter o_o
honestly, know i'm amateur , all, thought using reflection couldn't use constructor(neither other method) without of required parameters.
so: is there way map nested object custom constructor dynamic object automapper?
i have found solution this:
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)); }); });
i don't since seems have map object twice, works. appreaciate if came better though.
Comments
Post a Comment