Beispiel #1
0
        static IdentifiedObject InnerApplyDiffNew(IdentifiedObject currentState, PropertyModification[] modifications)
        {
            var type     = currentState.GetType();
            var accessor = TypeAccessor.Create(type);
            var newState = currentState.CloneNew();

            // set all non-modified properties
            var propertyNames = GetPropertyNames(type).Except(modifications.Select(m => m.Name));

            foreach (var property in propertyNames)
            {
                accessor[newState, property] = accessor[currentState, property];
            }

            // apply modified properties
            foreach (var modification in modifications)
            {
                var property = modification.Name
                               ?? throw new ArgumentException($@"Tried to get value from modification without a name: {FormatModification(modification)}");

                try
                {
                    accessor[newState, property] = modification.Value;

                    var valuePresenceMember = ValuePresenceMembers.GetOrAdd(type, _ => new ConcurrentDictionary <string, Member>())
                                              .GetOrAdd(property, _ => accessor.GetMembers().FirstOrDefault(m => m.Name == $"{property}Specified"));

                    if (valuePresenceMember != null)
                    {
                        accessor[newState, valuePresenceMember.Name] = !ReferenceEquals(modification.Value, null);
                    }
                }
                catch (Exception exception)
                {
                    throw new ApplicationException($"Could not set the value of the '{property}' property on {type} from modification {FormatModification(modification)}", exception);
                }
            }

            return((IdentifiedObject)newState);
        }