/// <summary> /// Sets the property value of the instance. /// </summary> /// <param name="instance">The instance.</param> /// <param name="memberName">The member name.</param> /// <param name="value">The value.</param> /// <returns><c>true</c> if the member was set successfully; otherwise <c>false</c>.</returns> public virtual bool SetMemberValue <TValue>(object instance, string memberName, TValue value) { try { var modelEditor = instance as IModelEditor; if (modelEditor != null && modelEditor.IsPropertyRegistered(memberName)) { // Don't use SetValueFastbutUnsecure, change notifications must be possible modelEditor.SetValue(memberName, value); return(true); } if (instance is IPropertySerializable propertySerializable) { if (propertySerializable.SetPropertyValue(memberName, value)) { return(true); } } if (instance is IFieldSerializable fieldSerializable) { if (fieldSerializable.SetFieldValue(memberName, value)) { return(true); } } var modelType = instance.GetType(); IFastMemberInvoker fastMemberInvoker = null; lock (_fastMemberInvokerCache) { if (!_fastMemberInvokerCache.TryGetValue(modelType, out fastMemberInvoker)) { fastMemberInvoker = GetFastMemberInvoker(modelType); _fastMemberInvokerCache[modelType] = fastMemberInvoker; } } if (fastMemberInvoker.SetPropertyValue(instance, memberName, value)) { return(true); } if (fastMemberInvoker.SetFieldValue(instance, memberName, value)) { return(true); } Log.Warning($"Failed to set member '{instance.GetType().GetSafeFullName(false)}.{memberName}' because the member cannot be found on the model"); } catch (Exception ex) { Log.Warning(ex, $"Failed to populate '{instance.GetType().GetSafeFullName(false)}.{memberName}', setting the member value threw an exception"); } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="AdvancedPropertyChangedEventArgs"/>"/> class. /// </summary> /// <param name="originalSender">The original sender.</param> /// <param name="latestSender">The latest sender.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="oldValue">The old value.</param> /// <param name="newValue">The new value.</param> /// <param name="isOldValueMeaningful">if set to <c>true</c>, the <paramref name="oldValue"/> has a meaningful value.</param> /// <param name="isNewValueMeaningful">if set to <c>true</c>, the <paramref name="newValue"/> has a meaningful value.</param> private AdvancedPropertyChangedEventArgs(object originalSender, object latestSender, string propertyName, object oldValue, object newValue, bool isOldValueMeaningful, bool isNewValueMeaningful) : base(propertyName) { OriginalSender = originalSender; LatestSender = latestSender; // Last resort to get the new value if (!isNewValueMeaningful && !string.IsNullOrEmpty(propertyName)) { var originalSenderType = originalSender?.GetType(); if (originalSenderType != null) { IFastMemberInvoker fastMemberInvoker = null; lock (FastMemberInvokersCache) { if (!FastMemberInvokersCache.TryGetValue(originalSenderType, out fastMemberInvoker)) { var fastMemberInvokerType = typeof(FastMemberInvoker <>).MakeGenericTypeEx(originalSenderType); fastMemberInvoker = (IFastMemberInvoker)Activator.CreateInstance(fastMemberInvokerType); FastMemberInvokersCache[originalSenderType] = fastMemberInvoker; } } if (fastMemberInvoker.TryGetPropertyValue(originalSender, propertyName, out newValue)) { isNewValueMeaningful = true; } } } OldValue = oldValue; NewValue = newValue; IsOldValueMeaningful = isOldValueMeaningful; IsNewValueMeaningful = isNewValueMeaningful; }
/// <summary> /// Gets the property value of the instance. /// </summary> /// <typeparam name="TValue">The type of the value to retrieve.</typeparam> /// <param name="instance">The instance.</param> /// <param name="memberName">The member name.</param> /// <param name="value">The member value to update.</param> /// <returns><c>true</c> if the member was retrieved; otherwise <c>false</c>.</returns> public virtual bool GetMemberValue <TValue>(object instance, string memberName, out TValue value) { try { var modelEditor = instance as IModelEditor; if (modelEditor != null && modelEditor.IsPropertyRegistered(memberName)) { value = modelEditor.GetValueFastButUnsecure <TValue>(memberName); return(true); } if (instance is IPropertySerializable propertySerializable) { object objectValue = null; if (propertySerializable.GetPropertyValue(memberName, ref objectValue)) { value = (TValue)objectValue; return(true); } } if (instance is IFieldSerializable fieldSerializable) { object objectValue = null; if (fieldSerializable.GetFieldValue(memberName, ref objectValue)) { value = (TValue)objectValue; return(true); } } var modelType = instance.GetType(); IFastMemberInvoker fastMemberInvoker = null; lock (_fastMemberInvokerCache) { if (!_fastMemberInvokerCache.TryGetValue(modelType, out fastMemberInvoker)) { fastMemberInvoker = GetFastMemberInvoker(modelType); _fastMemberInvokerCache[modelType] = fastMemberInvoker; } } if (fastMemberInvoker.TryGetPropertyValue(instance, memberName, out value)) { return(true); } if (fastMemberInvoker.TryGetFieldValue(instance, memberName, out value)) { return(true); } return(false); } catch (Exception ex) { Log.Warning(ex, "Failed to get value of member '{0}.{1}', skipping item during serialization", instance.GetType().GetSafeFullName(false), memberName); } value = default; return(false); }