using System; using System.Linq; namespace InABox.Core { public interface IEntityLink { Guid ID { get; set; } Guid Deleted { get; set; } bool Synchronise(object entity); bool Clear(); bool IsValid(); } public interface IEntityLink : IEntityLink { } public abstract class EntityLink : BaseObject, IEntityLink where T : BaseObject, new() { [DoNotSerialize] protected Entity LinkedEntity; //[Obsolete("Please supply linked Entity")] public EntityLink() { } public EntityLink(Entity entity) { LinkedEntity = entity; } [NullEditor] public abstract Guid ID { get; set; } [NullEditor] public Guid Deleted { get; set; } public virtual bool Synchronise(object Entity) { var result = false; var props = CoreUtils.PropertyList(GetType(), x => (!x.Name.Equals("ID") || Entity == null) && !x.DeclaringType.Equals(typeof(BaseObject)), false); foreach (var key in props.Keys) { if (CoreUtils.HasProperty(Entity.GetType(), key)) { var prop = CoreUtils.GetProperty(typeof(T), key); if (prop != null && prop.PropertyType.Equals(props[key]) && !prop.PropertyType.GetInterfaces().Any(x => x == typeof(IEntityLink))) { var oldvalue = CoreUtils.GetPropertyValue(this, key); var newvalue = CoreUtils.GetPropertyValue(Entity, key); if ((oldvalue == null && newvalue != null) || (oldvalue != null && !oldvalue.Equals(newvalue))) { result = true; try { CoreUtils.SetPropertyValue(this, key, newvalue); } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } } } } } if (LinkedEntity != null) foreach (var link in LinkedEntity.LinkedProperties(GetType())) { link.Update(this, LinkedEntity); result = true; } return result; } public bool Clear() { var result = false; var props = CoreUtils.PropertyList(GetType(), x => !x.Name.Equals("ID"), false); foreach (var key in props.Keys) { var prop = CoreUtils.GetProperty(typeof(T), key); if (prop != null && prop.PropertyType.Equals(props[key])) { var oldvalue = CoreUtils.GetPropertyValue(this, key); var newvalue = prop.PropertyType.Equals(typeof(string)) ? "" : Activator.CreateInstance(prop.PropertyType); if ((oldvalue == null && newvalue != null) || (oldvalue != null && !oldvalue.Equals(newvalue))) { result = true; CoreUtils.SetPropertyValue(this, key, newvalue); } } } return result; } protected override void DoPropertyChanged(string name, object before, object after) { if (IsObserving() && LinkedEntity != null) { var link = LinkedEntity.LinkedProperties(GetType()).FirstOrDefault(x => x.Source.Name.Equals(name)); if (link != null) link.Update(this, LinkedEntity); } } public bool IsValid() => !ID.Equals(Guid.Empty) && Deleted.Equals(Guid.Empty); } }