internal static void MapItemToModel(Item item, object model) { Assert.ArgumentNotNull(item, "item"); Assert.ArgumentNotNull(model, "model"); MapItemProperties(item, model); var type = model.GetType(); var plan = PlanCache.GetPlan(type.FullName, item.TemplateID); if (plan == null) { Log.Debug($"No plan for type {type.FullName} and template {item.TemplateID}. One will be recorded during the mapping.", typeof(ModelBuilder)); MapItemFieldsAndCreatePlan(item, model); } else { Log.Debug($"Using plan for type {plan.TypeFullName} and template {plan.TemplateID} for mapping.", typeof(ModelBuilder)); MapItemFieldsFromPlan(item, model, plan); } }
private static void MapItemFieldsAndCreatePlan(Item item, object model) { var type = model.GetType(); var plan = new MappingPlan(type.FullName, item.TemplateID); item.Fields.ReadAll(); // Here's the interesting part where we map Item fields to model properties. foreach (Field field in item.Fields) { if (ModelMapperConfiguration.Current.IgnoreStandardFields && field.Name.StartsWith("__")) { continue; // save some time. } // Get field mappers var mappers = ModelMapperConfiguration.Current.GetMappersForFieldType(field.Type); try { foreach (Type mapperType in mappers) { try { var mapper = (IFieldMapper)Activator.CreateInstance(mapperType); var status = mapper.Map(model, field); switch (status) { case FieldMapStatus.Exception: Log.Error($"Mapping field {field.Name} on Item {item.Name}: Exception handled by field mapper.", typeof(ModelBuilder)); break; case FieldMapStatus.TypeMismatch: Log.Warn($"Mapping field {field.Name} on Item {item.Name} to Model {type.Name} failed. The cause of the failure is usually a type mismatch. Is the right field mapper running for this field?", typeof(ModelBuilder)); break; case FieldMapStatus.ExplicitIgnore: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: explicitly ignored", typeof(ModelBuilder)); break; case FieldMapStatus.NoProperty: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: no matching property name.", typeof(ModelBuilder)); break; case FieldMapStatus.FieldEmpty: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: field was empty.", typeof(ModelBuilder)); plan.AddField(field.ID); break; case FieldMapStatus.ValueEmpty: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: processed value was empty.", typeof(ModelBuilder)); plan.AddField(field.ID); break; case FieldMapStatus.Success: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: success.", typeof(ModelBuilder)); plan.AddField(field.ID); break; } } catch (TypeLoadException ex) { Log.Error($"ModelMapper was unable to create FieldMapper type {mapperType.Name}", ex, typeof(ModelBuilder)); throw; } catch (Exception ex) { Log.Error($"Mapping field {field.Name} on Item {item.Name} to Model {type.Name} failed.", ex, typeof(ModelBuilder)); throw; } } PlanCache.AddPlan(plan); } catch (Exception) { Log.Warn($"ModelMapper did not cache the plan for {item.Name} because there were errors during the mapping process.", typeof(ModelBuilder)); } } }
private static PlanCache CreateNewPlanCache() { var output = new PlanCache(); return(output); }