using System.Linq.Expressions; using System.Reflection; namespace zero.Architecture; public class BlueprintField where T : ZeroEntity { public Expression> Expression { get; private set; } public PropertyInfo PropertyInfo { get; private set; } public string FieldName { get; private set; } Action _applyHook { get; set; } Func _selectorFunc = null; internal BlueprintField(Expression> selector) { Expression = selector; FieldName = selector.GetPropertyPath(out MemberExpression member); PropertyInfo = member?.Member as PropertyInfo; if (PropertyInfo == null) { throw new ArgumentException("selector parameter has to be a property selector"); } if (FieldName.IsNullOrEmpty()) { throw new Exception("Could not find a matching field name"); } } public virtual void Apply(T blueprint, T model) { if (_applyHook != null) { _applyHook(blueprint, model); return; } _selectorFunc ??= Expression.Compile(); PropertyInfo.SetValue(model, _selectorFunc(blueprint)); } public virtual void OnUpdate(Action onUpdate) { _applyHook = onUpdate; } }