public static IDtoCapable ToConcrete(this IDtoBase dto) { var dtoType = dto.GetDtoType(); var concrete = dtoType.CreateConcreteInstance(); dto.PatchConcrete(concrete); // return... return(concrete); }
public static void PatchConcrete(this IDtoBase dto, IDtoCapable concrete, IEnumerable <string> permittedFields = null) { var dtoType = dto.GetDtoType(); // ok... var wasNew = dto.IsNew(); concrete.OnPatching(dto, wasNew); // if we don't have permitted fields, get them, but skip the key... if (permittedFields == null) { var toUse = new List <string>(); var et = concrete.GetType().ToEntityType(); foreach (EntityField field in et.Fields) { if (!(field.IsKey())) { toUse.Add(field.Name); } } // set... permittedFields = toUse; } // walk... var values = dto.GetTouchedValues(); foreach (var field in values.Keys) { var value = values[field]; // are we allowed to set it? if (permittedFields.Contains(field.Name, StringComparer.InvariantCultureIgnoreCase)) { // member... var member = concrete.EntityType.GetMember(field.Name, OnNotFound.ReturnNull); if (member != null) { var canSet = true; if (member is EntityField && ((EntityField)member).IsKey()) { canSet = false; } if (canSet) { member.SetValue(concrete, value, BootFX.Common.Entities.SetValueReason.UserSet); } } else { var prop = concrete.EntityType.Type.GetProperty(field.Name, BindingFlags.Instance | BindingFlags.Public); if (prop != null && prop.CanWrite) { try { prop.SetValue(concrete, value); } catch (Exception ex) { throw new InvalidOperationException(string.Format("Failed to set value '{0}' on '{1}'.\r\nValue: {2}", prop.Name, prop.DeclaringType.Name, value), ex); } } else { // don't do anything in here -- this needs to be loose.... } } } } // signal... concrete.OnPatched(dto, wasNew); }