c# - AutoMapper conditional map for recursive model -
i've got recursive model class following definition:
public class itemfilterblockgroup { public itemfilterblockgroup(string groupname, itemfilterblockgroup parent, bool advanced = false) { groupname = groupname; parentgroup = parent; advanced = advanced; childgroups = new list<itemfilterblockgroup>(); } public string groupname { get; private set; } public bool advanced { get; private set; } public itemfilterblockgroup parentgroup { get; private set; } public list<itemfilterblockgroup> childgroups { get; private set; } }
it has property called childgroups list of - used build hierarchical model. i'm trying map model view models, conditionally. (depending on ui setting) want include child objects advanced = false, , want include models.
currently i'm achieving nasty hack involves mapper.reset() , runtime re-definition of maps - not , presents multiple problems:
mapper.reset(); if (showadvanced) { mapper.createmap<itemfilterblockgroup, itemfilterblockgroupviewmodel>(); } else { mapper.createmap<itemfilterblockgroup, itemfilterblockgroupviewmodel>() .formember(dest => dest.childgroups, opts => opts.mapfrom(from => from.childgroups.where(c => c.advanced == false))); } var mappedviewmodels = mapper.map<observablecollection<itemfilterblockgroupviewmodel>>(blockgroups);
given example input hierarchy of models:
root (advanced = false) +-child 1 (advanced = true) +-child 2 (advanced = false) +-child 3 (advanced = false) +-child 3 sub child 1 (advanced = false) +-child 3 sub child 2 (advanced = true)
the first createmap definition returns hierarchy untouched, , second createmap definition (with advanced parameter) returns modified hierarchy (all advanced = true models , children excluded mapping):
root (advanced = false) +-child 2 (advanced = false) +-child 3 (advanced = false) +-child 3 sub child 1 (advanced = false)
how can parameterise showadvanced condition , achieve same result single createmap definition? i've searched lot right solution, tried resolveusing, customresolvers, no avail.
you can use context option items
collection pass values map function @ runtime:
var showadvanced = true; var mappedviewmodels = mapper.map<observablecollection<itemfilterblockgroupviewmodel>>( blockgroups, options => options.items["includeadvanced"] = showadvanced);
and use them anywhere context available construct destination object. within resolveusing
or constructusing
methods example:
mapper.createmap<itemfilterblockgroup, itemfilterblockgroupviewmodel>() .formember(destination => destination.childgroups, options => options.resolveusing( (resolution) => { var includeadvanced = (bool)resolution.context.options.items["includeadvanced"]; var source = (itemfilterblockgroup)resolution.context.sourcevalue; if(includeadvanced) return source.childgroups; else return source.childgroups.where(c => c.advanced == false); }));
if usage of weakly typed dictionary values pass flag argument not pretty suggest encapsulate logic within 2 separated methods, in martin fowler article example.
Comments
Post a Comment