/// <summary> /// Adds a Plan to the cache. /// </summary> /// <param name="plan">The plan to add.</param> public static void AddPlan(MappingPlan plan) { var key = GetKey(plan); if (Current.Cache.ContainsKey(key)) { Log.Debug($"MappingPlan: Plan for class {plan.TypeFullName} and template {plan.TemplateID} already cached. Replacing.", typeof(PlanCache)); Current.Cache[key] = plan; return; } Log.Debug($"ModelMapping.PlanCache: Plan for class {plan.TypeFullName} added.", typeof(PlanCache)); Current.Cache.Add(key, 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 void MapItemFieldsFromPlan(Item item, object model, MappingPlan plan) { var type = model.GetType(); Log.Debug($"Mapping Item {item.Name} using a cached mapping plan for {type.FullName}", typeof(ModelBuilder)); item.Fields.ReadAll(); var fieldNames = plan.GetFieldIDs(); // Here's the interesting part where we map Item fields to model properties. foreach (var fieldName in fieldNames) { var field = item.Fields[fieldName]; // Get field mappers var mappers = ModelMapperConfiguration.Current.GetMappersForFieldType(field.Type); 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.", 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)); break; case FieldMapStatus.ValueEmpty: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: processed value was empty.", typeof(ModelBuilder)); break; case FieldMapStatus.Success: Log.Debug($"Mapping field {field.Name} on Item {item.Name}: success.", typeof(ModelBuilder)); break; } } catch (TypeLoadException ex) { Log.Error($"ModelMapper was unable to create FieldMapper type {mapperType.Name}", ex, typeof(ModelBuilder)); } catch (Exception ex) { Log.Error($"Mapping field {field.Name} on Item {item.Name} to Model {type.Name} failed.", ex, typeof(ModelBuilder)); } } } }
private static string GetKey(MappingPlan plan) { return(GetKey(plan.TypeFullName, plan.TemplateID)); }