| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 | using System;using System.Collections.Generic;using System.Diagnostics.CodeAnalysis;using System.Linq;using System.Linq.Expressions;namespace InABox.Core{    public interface ISubObject    {        BaseObject GetLinkedParent();        void SetLinkedParent(BaseObject obj);        string GetLinkedPath();        void SetLinkedPath(string path);    }    public static class LinkedProperties    {        private static readonly Dictionary<Type, List<ILinkedProperty>> _LinkedProperties = new Dictionary<Type, List<ILinkedProperty>>();                public static void Register<TLinkedEntity, TEntityLink, TType>(Expression<Func<TLinkedEntity,TEntityLink>> path, Expression<Func<TEntityLink, TType>> source,            Expression<Func<TLinkedEntity, TType>> target)        {            var map = new LinkedProperty<TLinkedEntity, TEntityLink, TType>(path, source, target);            if(!_LinkedProperties.TryGetValue(map.Type, out var props))            {                props = new List<ILinkedProperty>();                _LinkedProperties[map.Type] = props;            }            if(!props.Any(x => x.Equals(map)))            {                props.Add(map);            }        }        /*public static IEnumerable<ILinkedProperty> Find(object parent, object path)        {            var all =  _LinkedProperties.Where(x => x.Type == parent.GetType());            var filtered =  all.Where(x => CoreUtils.GetPropertyValue(parent,x.Path)?.GetType() == path?.GetType());            return filtered;        }*/        private static BaseObject GetParent(ISubObject link)        {            while (true)            {                var parent = link.GetLinkedParent();                if(parent is IEntityLink parentLink)                {                    link = parentLink;                }                else                {                    return parent;                }            }        }        private static string GetPath(ISubObject link)        {            var path = link.GetLinkedPath();            while (true)            {                var parent = link.GetLinkedParent();                if (parent is IEntityLink parentLink)                {                    link = parentLink;                    path = $"{link.GetLinkedPath()}.{path}";                }                else                {                    return path;                }            }        }        public static IEnumerable<ILinkedProperty> FindAll(Type parent)        {            if (_LinkedProperties.TryGetValue(parent, out var props))            {                return props;            }            return Enumerable.Empty<ILinkedProperty>();        }        public static IEnumerable<ILinkedProperty> Find(ISubObject subObject, out BaseObject parent)        {            parent = GetParent(subObject);            if (!_LinkedProperties.TryGetValue(parent.GetType(), out var props))            {                return Enumerable.Empty<ILinkedProperty>();            }            var path = GetPath(subObject);            return props.Where(x => x.Path == path);        }        public static bool Find(ISubObject subObject, string name, [NotNullWhen(true)] out ILinkedProperty? property, out BaseObject parent)        {            property = null;            parent = GetParent(subObject);            if (parent == null)                return false;            if(!_LinkedProperties.TryGetValue(parent.GetType(), out var props))                return false;            var path = GetPath(subObject);            property = props.FirstOrDefault(x => String.Equals($"{x.Path}{(String.IsNullOrWhiteSpace(x.Path) ? "" : ".")}{x.Source}", $"{path}{(String.IsNullOrWhiteSpace(path) ? "" : ".")}{name}"));            return property != null;        }            }}
 |