using System; using System.Collections.Generic; using System.Reflection; namespace dezentrale.core { public class ReplaceReflectEntity where T : ReplaceReflectEntity //Only child classes are allowed as T parameters { [System.Xml.Serialization.XmlIgnore] public List AllowedObjectFields { get; set; } = new List(); protected ReplaceReflectEntity() { } public T ReplaceReflect(object o) { //return ReplaceReflect(o, null); return ReplaceReflect(o, o.GetType().Name); } public T ReplaceReflect(object o, string oTypeName) { T ret = (T) this.MemberwiseClone(); PropertyInfo[] objProperties = o.GetType().GetProperties(); foreach (var childProperty in ret.GetType().GetProperties()) { if (childProperty.PropertyType != typeof(string)) continue; if (!childProperty.CanRead) continue; if (!childProperty.CanWrite) continue; string propVal = (string)childProperty.GetValue(ret, null); if (propVal == null) continue; bool changed = false; foreach (PropertyInfo objProperty in objProperties) { if (!objProperty.CanRead) continue; //check if objProperty occurs in mailProperty contents, then replace string token; string tokenValue; if (oTypeName == null) { token = $"{{{objProperty.Name}}}"; } else { token = $"{{{oTypeName}.{objProperty.Name}}}"; } try { tokenValue = objProperty.GetValue(o, null).ToString(); } catch (NullReferenceException) { //Console.WriteLine($"FormMail.ReplaceReflect({o}): property {token}: {ex.Message}"); continue; } if (propVal.Contains(token)) { //NOTE: This is problematic because it allows the user to generate recursive replacements by setting e.g. the Nickname to "{PgpFingerprint}" propVal = propVal.Replace(token, tokenValue); changed = true; } } if (changed) { childProperty.SetValue(ret, propVal, null); } } return ret; } } }