LinkedProperty.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. using System.Reflection;
  5. using FluentResults;
  6. namespace InABox.Core
  7. {
  8. public interface ILinkedProperty
  9. {
  10. Type Type { get; }
  11. String Path { get; }
  12. String Source { get; }
  13. String Target { get; }
  14. void Update(object? from, object? to);
  15. /// <summary>
  16. /// This equality comparer checks against type, path, source and target
  17. /// </summary>
  18. /// <param name="obj"></param>
  19. /// <returns></returns>
  20. bool Equals(object obj);
  21. }
  22. public class LinkedProperty<TLinkedEntity, TEntityLink, TType> : ILinkedProperty
  23. where TLinkedEntity : class
  24. where TEntityLink : class
  25. {
  26. public Type Type => typeof(TLinkedEntity);
  27. public String Path { get; }
  28. private Func<TEntityLink?, TType> _source;
  29. public String Source { get; }
  30. public String Target { get; }
  31. private readonly Func<TLinkedEntity?, TType, Result<TType>>? _func;
  32. public override string ToString()
  33. {
  34. return $"{Type.EntityName().Split('.').Last()}: {Path}{(String.IsNullOrWhiteSpace(Path) ? "" : ".")}{Source} => {Target}";
  35. }
  36. public LinkedProperty(Expression<Func<TLinkedEntity, TEntityLink>> path,
  37. Expression<Func<TEntityLink?, TType>> source,
  38. Expression<Func<TLinkedEntity?, TType>> target,
  39. Func<TLinkedEntity?,TType, Result<TType>>? func = null)
  40. {
  41. Path = CoreUtils.GetFullPropertyName(path, ".");
  42. Source = CoreUtils.GetFullPropertyName(source, ".");
  43. Target = CoreUtils.GetFullPropertyName(target,".");
  44. _func = func;
  45. _source = source.Compile();
  46. }
  47. public void Update(object? from, object? to)
  48. {
  49. if (from != null && to != null)
  50. {
  51. var value = _source.Invoke(from as TEntityLink);
  52. //var value = CoreUtils.GetPropertyValue(from, Source);
  53. if (_func != null)
  54. {
  55. var result = _func(to as TLinkedEntity, value);
  56. if (!result.IsSuccess)
  57. return;
  58. value = result.Value;
  59. }
  60. CoreUtils.SetPropertyValue(to, Target, value);
  61. }
  62. }
  63. public override bool Equals(object obj)
  64. {
  65. if (obj is ILinkedProperty src)
  66. {
  67. return
  68. (obj as ILinkedProperty).Type == Type &&
  69. String.Equals(src.Path,Path)
  70. && String.Equals(src.Source, Source)
  71. && String.Equals(src.Target, Target);
  72. }
  73. return false;
  74. }
  75. }
  76. }