123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using System;
- using System.Collections;
- 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 class SubObjectOriginalValues : IOriginalValues
- {
- private ISubObject Object { get; set; }
- private IOriginalValues? _rootDictionary;
- private IOriginalValues RootDictionary
- {
- get
- {
- _rootDictionary ??= LinkedProperties.GetParent(Object).OriginalValueList;
- return _rootDictionary;
- }
- }
- private string? _rootPath;
- /// <summary>
- /// Path of this sub object according to the root, suffixed with a "."
- /// </summary>
- private string RootPath
- {
- get
- {
- _rootPath ??= $"{LinkedProperties.GetPath(Object)}.";
- return _rootPath;
- }
- }
- public SubObjectOriginalValues(ISubObject obj)
- {
- Object = obj;
- }
- private string ChangeKey(string key) => $"{RootPath}{key}";
- public bool ContainsKey(string key)
- {
- return RootDictionary.ContainsKey(ChangeKey(key));
- }
- public void Clear()
- {
- foreach(var (k, v) in RootDictionary)
- {
- if (k.StartsWith(RootPath))
- {
- RootDictionary.Remove(k);
- }
- }
- }
- public void Remove(string key)
- {
- RootDictionary.Remove(ChangeKey(key));
- }
- public bool TryAdd(string key, object? value)
- {
- return RootDictionary.TryAdd(ChangeKey(key), value);
- }
- public bool TryGetValue(string key, out object? value)
- {
- return RootDictionary.TryGetValue(ChangeKey(key), out value);
- }
- public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
- {
- return RootDictionary.Where(x => x.Key.StartsWith(RootPath)).Select(x => new KeyValuePair<string, object?>(x.Key[RootPath.Length..], x.Value)).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- public object? this[string key]
- {
- get => RootDictionary[ChangeKey(key)];
- set => RootDictionary[ChangeKey(key)] = value;
- }
- }
- public class SubObjectLoadedColumns : ILoadedColumns
- {
- private ISubObject Object { get; set; }
- private ILoadedColumns? _rootSet;
- private ILoadedColumns RootSet
- {
- get
- {
- _rootSet ??= LinkedProperties.GetParent(Object).LoadedColumns;
- return _rootSet;
- }
- }
- private string? _rootPath;
- /// <summary>
- /// Path of this sub object according to the root, suffixed with a "."
- /// </summary>
- private string RootPath
- {
- get
- {
- _rootPath ??= $"{LinkedProperties.GetPath(Object)}.";
- return _rootPath;
- }
- }
- public SubObjectLoadedColumns(ISubObject obj)
- {
- Object = obj;
- }
- private string ChangeKey(string key) => $"{RootPath}{key}";
- public bool Add(string key)
- {
- return RootSet.Add(ChangeKey(key));
- }
- public bool Contains(string key)
- {
- return RootSet.Contains(ChangeKey(key));
- }
- public IEnumerator<string> GetEnumerator()
- {
- return RootSet.Where(x => x.StartsWith(RootPath)).Select(x => x[RootPath.Length..]).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- }
- 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, Func<TLinkedEntity,TType, Result<TType, string>>? func = null)
- where TLinkedEntity : class
- where TEntityLink : class
- {
- var map = new LinkedProperty<TLinkedEntity, TEntityLink, TType>(path, source, target, func);
- 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;
- }*/
- public static BaseObject GetParent(ISubObject link)
- {
- while (true)
- {
- var parent = link.GetLinkedParent();
- if(parent is ISubObject parentLink)
- {
- link = parentLink;
- }
- else
- {
- return parent;
- }
- }
- }
- public static string GetPath(ISubObject link)
- {
- var path = link.GetLinkedPath();
- while (true)
- {
- var parent = link.GetLinkedParent();
- if (parent is ISubObject 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}{(x.Path.IsNullOrWhiteSpace() ? "" : ".")}{x.Source}",
- $"{path}{(path.IsNullOrWhiteSpace() ? "" : ".")}{name}"));
- return property != null;
- }
-
- }
- }
|