Quellcode durchsuchen

Fixed LinkedProperty() functionality

Frank van den Bos vor 2 Jahren
Ursprung
Commit
26ee1690e2

+ 8 - 1
InABox.Core/Dimensions/DimensionUnitLink.cs

@@ -4,7 +4,14 @@ namespace InABox.Core
 {
     public abstract class DimensionUnitLink<T> : EntityLink<T>, IDimensionUnit where T : DimensionUnit, new()
     {
-        
+        protected DimensionUnitLink()
+        {
+        }
+
+        protected DimensionUnitLink(Func<Entity>? entity) : base(entity)
+        {
+        }
+
         [RequiredColumn]
         public override Guid ID { get; set; }
         

+ 14 - 10
InABox.Core/Dimensions/Dimensions.cs

@@ -4,11 +4,15 @@ using System.Collections.Generic;
 namespace InABox.Core
 {
 
-    public abstract class Dimensions<TLink,TUnit> : BaseObject, IEnclosedEntity, IDimensions 
+    public abstract class Dimensions<TLink,TUnit> : EnclosedEntity, IDimensions 
         where TLink : DimensionUnitLink<TUnit>, new() 
         where TUnit : DimensionUnit, new()
     {
+
+        public Dimensions() : base() { }
         
+        public Dimensions(Func<Entity> entity) : base(entity) { }
+
         [EditorSequence(1)]
         [RequiredColumn]
         [Caption("Sizing", IncludePath = false)]
@@ -61,15 +65,15 @@ namespace InABox.Core
         protected override void Init()
         {
             base.Init();
-            Unit = new TLink();
-            Unit.PropertyChanged += (sender, args) =>
-            {
-                var unit = sender as DimensionUnitLink<TUnit>;
-                DoPropertyChanged(
-                    String.Format("Unit.{0}",args.PropertyName), 
-                    unit.GetOriginalValue<DimensionUnitLink<TUnit>,object>(args.PropertyName), 
-                    CoreUtils.GetPropertyValue(unit,args.PropertyName));
-            };
+            Unit = Activator.CreateInstance(typeof(TLink), new object[] { new Func<Entity>(LinkedEntity) }) as TLink;
+            // Unit.PropertyChanged += (sender, args) =>
+            // {
+            //     var unit = sender as DimensionUnitLink<TUnit>;
+            //     DoPropertyChanged(
+            //         String.Format("Unit.{0}",args.PropertyName), 
+            //         unit.GetOriginalValue<DimensionUnitLink<TUnit>,object>(args.PropertyName), 
+            //         CoreUtils.GetPropertyValue(unit,args.PropertyName));
+            // };
         }
         
         private bool bCalculating = false;

+ 40 - 0
InABox.Core/EnclosedEntity.cs

@@ -0,0 +1,40 @@
+using System;
+using System.Linq;
+
+namespace InABox.Core
+{
+    
+    public interface IEnclosedEntity
+    {
+    }
+    
+    public abstract class EnclosedEntity : BaseObject, IEnclosedEntity
+    {
+        
+        private Func<Entity>? _linkedentity;
+        
+        [DoNotSerialize]
+        protected Entity? LinkedEntity() => _linkedentity?.Invoke();
+
+        //[Obsolete("Please supply linked Entity")]
+        public EnclosedEntity()
+        {
+        }
+
+        public EnclosedEntity(Func<Entity>? entity) 
+        {
+            _linkedentity = entity;
+        }
+        
+        protected override void DoPropertyChanged(string name, object before, object after)
+        {
+            var le = LinkedEntity();
+            if (IsObserving() && le != null)
+            {
+                var link = le.LinkedProperties(this).FirstOrDefault(x => x.Source.Equals(name));
+                if (link != null)
+                    link.Update(this, le);
+            }
+        }
+    }
+}

+ 10 - 19
InABox.Core/Entity.cs

@@ -15,10 +15,8 @@ namespace InABox.Core
         public virtual string Password { get; set; }
     }
 
-    public interface IEnclosedEntity
-    {
-    }
-    
+
+
     public interface IEntity
     {
         Guid ID { get; set; }
@@ -308,26 +306,19 @@ namespace InABox.Core
 
         // Why?
         [DoNotSerialize]
-        private static readonly List<LinkedProperty> _LinkedProperties = new List<LinkedProperty>();
+        private static readonly List<ILinkedProperty> _LinkedProperties = new List<ILinkedProperty>();
 
-        public virtual void LinkProperty<TEntityLink, TLinkedEntity>(Expression<Func<TEntityLink, object>> source,
-            Expression<Func<TLinkedEntity, object>> target)
+        public virtual void LinkProperty<TLinkedEntity, TEntityLink, TType>(Expression<Func<TLinkedEntity,TEntityLink>> path, Expression<Func<TEntityLink, TType>> source,
+            Expression<Func<TLinkedEntity, TType>> target)
         {
-            var map = LinkedProperty.Create(source, target);
-            if (!_LinkedProperties.Any(x =>
-                    x.Source.DeclaringType.Equals(typeof(TEntityLink)) && x.Source.Name.Equals(map.Source.Name) &&
-                    x.Source.Name.Equals(map.Source.Name) && x.Target.DeclaringType.Equals(typeof(TLinkedEntity)) &&
-                    x.Target.Name.Equals(map.Target.Name)))
-                _LinkedProperties.Add(LinkedProperty.Create(source, target));
+            var map = new LinkedProperty<TLinkedEntity, TEntityLink, TType>(path, source, target);
+            if (!_LinkedProperties.Any(x => x.Equals(map)))
+                _LinkedProperties.Add(map);
         }
 
-        public IEnumerable<LinkedProperty> LinkedProperties(Type type)
+        public IEnumerable<ILinkedProperty> LinkedProperties(object path)
         {
-            var result = _LinkedProperties.Where(x =>
-                (x.Source.DeclaringType.Equals(type) || x.Source.DeclaringType.IsSubclassOf(type)) &&
-                (x.Target.DeclaringType.Equals(GetType()) || x.Target.DeclaringType.IsSubclassOf(GetType()))
-            );
-            return result;
+            return _LinkedProperties.Where(x => (x.Type == this.GetType()) && (CoreUtils.GetPropertyValue(this,x.Path) == path));
         }
 
         #endregion

+ 15 - 9
InABox.Core/EntityLink.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Dynamic;
 using System.Linq;
 
 namespace InABox.Core
@@ -21,17 +22,20 @@ namespace InABox.Core
 
     public abstract class EntityLink<T> : BaseObject, IEntityLink<T> where T : BaseObject, new()
     {
+
+        private Func<Entity>? _linkedentity;
+        
         [DoNotSerialize]
-        protected Entity LinkedEntity;
+        protected Entity? LinkedEntity() => _linkedentity?.Invoke();
 
         //[Obsolete("Please supply linked Entity")]
         public EntityLink()
         {
         }
 
-        public EntityLink(Entity entity)
+        public EntityLink(Func<Entity>? entity) 
         {
-            LinkedEntity = entity;
+            _linkedentity = entity;
         }
 
         [NullEditor]
@@ -70,10 +74,11 @@ namespace InABox.Core
                 }
             }
 
-            if (LinkedEntity != null)
-                foreach (var link in LinkedEntity.LinkedProperties(GetType()))
+            var le = LinkedEntity();
+            if (le != null)
+                foreach (var link in le.LinkedProperties(this))
                 {
-                    link.Update(this, LinkedEntity);
+                    link.Update(this, le);
                     result = true;
                 }
 
@@ -104,11 +109,12 @@ namespace InABox.Core
 
         protected override void DoPropertyChanged(string name, object before, object after)
         {
-            if (IsObserving() && LinkedEntity != null)
+            var le = LinkedEntity();
+            if (IsObserving() && le != null)
             {
-                var link = LinkedEntity.LinkedProperties(GetType()).FirstOrDefault(x => x.Source.Name.Equals(name));
+                var link = le.LinkedProperties(this).FirstOrDefault(x => x.Source.Equals(name));
                 if (link != null)
-                    link.Update(this, LinkedEntity);
+                    link.Update(this, le);
             }
         }
 

+ 35 - 17
InABox.Core/LinkedProperty.cs

@@ -4,33 +4,51 @@ using System.Reflection;
 
 namespace InABox.Core
 {
-    public class LinkedProperty
+    public interface ILinkedProperty
     {
-        private LinkedProperty(PropertyInfo source, PropertyInfo target)
+        Type Type { get; }
+        String Path { get; }
+        String Source { get; }
+        String Target { get; }
+        void Update(object? from, object? to);
+        bool Equals(object obj);
+    }
+
+    public class LinkedProperty<TLinkedEntity, TEntityLink, TType> : ILinkedProperty
+    {
+        public Type Type => typeof(TLinkedEntity);
+        public String Path { get; }
+        public String Source { get; }
+        public String Target { get; }
+        
+        public LinkedProperty(Expression<Func<TLinkedEntity, TEntityLink>> path, 
+            Expression<Func<TEntityLink, TType>> source,
+            Expression<Func<TLinkedEntity, TType>> target)
         {
-            Source = source;
-            Target = target;
+            Path = CoreUtils.GetFullPropertyName(path, ".");
+            Source = CoreUtils.GetFullPropertyName(source, ".");
+            Target = CoreUtils.GetFullPropertyName(target,".");
         }
 
-        public PropertyInfo Source { get; }
-        public PropertyInfo Target { get; }
-
-        public static LinkedProperty Create<TEntityLink, TLinkedEntity>(Expression<Func<TEntityLink, object>> source,
-            Expression<Func<TLinkedEntity, object>> target)
+        public void Update(object? from, object? to)
         {
-            return new LinkedProperty(
-                CoreUtils.GetPropertyFromExpression(source),
-                CoreUtils.GetPropertyFromExpression(target)
-            );
+            if (from != null && to != null)
+            {
+                var value = CoreUtils.GetPropertyValue(from, Source);
+                CoreUtils.SetPropertyValue(to, Target, value);
+            }
         }
 
-        public void Update(object from, object to)
+        public override bool Equals(object obj)
         {
-            if (from != null && to != null)
+            if (obj is ILinkedProperty src)
             {
-                var value = Source.GetValue(from);
-                Target.SetValue(to, value);
+                return 
+                    String.Equals(src.Path,Path)
+                       && String.Equals(src.Source, Source)
+                       && String.Equals(src.Target, Target);
             }
+            return false;
         }
     }
 }