private void AddOrMergeIndexedArgumentValues(int key, ValueHolder newValue)
        {
            ValueHolder currentValue;
            IMergable   mergable = newValue.Value as IMergable;

            if (_indexedArgumentValues.TryGetValue(key, out currentValue) && mergable != null)
            {
                if (mergable.MergeEnabled)
                {
                    newValue.Value = mergable.Merge(currentValue.Value);
                }
            }
            _indexedArgumentValues[key] = newValue;
        }
        /// <summary>
        /// Merges the value of the supplied 'new' <see cref="PropertyValue"/> with that of
        /// the current <see cref="PropertyValue"/> if merging is supported and enabled.
        /// </summary>
        /// <see cref="IMergable"/>
        /// <param name="newPv">The new pv.</param>
        /// <param name="currentPv">The current pv.</param>
        /// <returns>The possibly merged PropertyValue</returns>
        private PropertyValue MergeIfRequired(PropertyValue newPv, PropertyValue currentPv)
        {
            object    val      = newPv.Value;
            IMergable mergable = val as IMergable;

            if (mergable != null)
            {
                if (mergable.MergeEnabled)
                {
                    object merged = mergable.Merge(currentPv.Value);
                    return(new PropertyValue(newPv.Name, merged));
                }
            }
            return(newPv);
        }
Beispiel #3
0
        void Microsoft.Samples.WindowsAzure.ServiceManagement.IMergable <T> .Merge(T other)
        {
            object       obj      = null;
            Mergable <T> mergable = other;

            foreach (KeyValuePair <string, object> propertyStore in mergable.PropertyStore)
            {
                if (this.PropertyStore.TryGetValue(propertyStore.Key, out obj))
                {
                    IMergable mergable1 = obj as IMergable;
                    if (mergable1 != null)
                    {
                        mergable1.Merge(propertyStore.Value);
                        continue;
                    }
                }
                this.PropertyStore[propertyStore.Key] = propertyStore.Value;
            }
        }
Beispiel #4
0
 /// <summary>
 ///     Merges <paramref name="right"/> with current dictionary, appending all lists and merging dictionaries.
 /// </summary>
 /// <param name="left">The object that will accept all merges.</param>
 /// <param name="right">The dictionary to take data from.</param>
 /// <param name="preference">See the enum values docs.</param>
 public static void Merge(IMergable left, object right, MergePrefer preference)
 {
     merging_core(left, right, preference);
 }
Beispiel #5
0
        private static object merging_core_imerger(IMergable left, object right, MergePrefer preference)
        {
            //handle nulls
            if (left == null && right != null)
            {
                return(right);
            }

            if (right == null)
            {
                return(left);
            }

            if (ReferenceEquals(left, right))
            {
                return(left);
            }

            //handle kv pairs
            if (right is IEnumerable <KeyValuePair <string, object> > rightenumerable && !(right is IDictionary))
            {
                right = new Dict(rightenumerable);
            }

            //handle dict
            if (right is IDictionary rightdict)
            {
                //handle empty, fixed or readonly
                if (rightdict.Count == 0)
                {
                    return(left);
                }

                if (!left.IsExpandable)
                {
                    foreach (var leftkey in left.Keys)
                    {
                        if (rightdict.Contains(leftkey))
                        {
                            left.Set(leftkey, rightdict[leftkey]);
                        }
                    }
                }
                else
                {
                    //get keys to process
                    var mainkeys    = left.Keys.Cast <object>().ToList();
                    var otherkeys   = rightdict.Keys.Cast <object>().ToList();
                    var sharedkeys  = mainkeys.Intersect(otherkeys); //keys both share
                    var missingkeys = otherkeys.Except(mainkeys);    //keys only otherdict has

                    object current_key = null;                       //for exception handling
                    try {
                        //handle merging of shared keys
                        foreach (var key in sharedkeys)
                        {
                            current_key = key;
                            var leftkey = (key as string) ?? key.ToString();
                            try {
                                left.Set(leftkey, merging_core(left.Get(leftkey), rightdict[key], preference)); //try to merge both values before returning.
                            } catch (KeyNotFoundException) { } //has no setter.
                        }

                        //handle settings of missing keys in sharedkeys
                        foreach (var key in missingkeys)
                        {
                            current_key = key;
                            try {
                                left.Set(
                                    (key as string) ?? throw new InvalidOperationException("A key for IMergable must be a string."),
                                    _trycopy(rightdict[key])
                                    ); //try to merge both values before returning.
                            } catch (KeyNotFoundException) { } //has no setter.
                        }
                    } catch (Exception e) {
                        throw new DictMergingException($"Merging failed during merge of key '{current_key}', see inner exception.", e);
                    }
                }

                return(left);
            }

            //handle dict
            if (right is IMergable rightmergable)
            {
                //handle empty, fixed or readonly
                if (rightmergable.Count == 0)
                {
                    return(left);
                }
                var rightkeys = rightmergable.Keys.ToArray();
                if (!left.IsExpandable)
                {
                    if (preference == MergePrefer.New)
                    {
                        foreach (var leftkey in left.Keys)
                        {
                            if (rightkeys.Contains(leftkey))
                            {
                                left.Set(leftkey, rightmergable.Get(leftkey));
                            }
                        }
                    }
                }
                else
                {
                    //get keys to process
                    var mainkeys    = left.Keys.Cast <object>().ToList();
                    var otherkeys   = rightkeys.Cast <object>().ToList();
                    var sharedkeys  = mainkeys.Intersect(otherkeys); //keys both share
                    var missingkeys = otherkeys.Except(mainkeys);    //keys only otherdict has

                    string current_key = null;                       //for exception handling
                    try {
                        //handle merging of shared keys
                        foreach (var key in sharedkeys)
                        {
                            var leftkey = current_key = (string)key;
                            try {
                                left.Set(leftkey, merging_core(left.Get(leftkey), rightmergable.Get(leftkey), preference)); //try to merge both values before returning.
                            } catch (KeyNotFoundException) { } //has no setter.
                        }

                        //handle settings of missing keys in sharedkeys
                        foreach (var o_key in missingkeys)
                        {
                            var key = current_key = (string)o_key;
                            try {
                                left.Set(key, _trycopy(rightmergable.Get(current_key))); //try to merge both values before returning.
                            } catch (KeyNotFoundException) { } //has no setter.
                        }
                    } catch (Exception e) {
                        throw new DictMergingException($"Merging failed during merge of key '{current_key}', see inner exception.", e);
                    }
                }

                return(left);
            }

            return(preference == MergePrefer.Old ? left : right);
        }