Beispiel #1
0
        /// <summary>
        /// Recursively visits through the properties of the object and based on mode takes appropriate action.
        /// </summary>
        /// <param name="obj">Object to visit</param>
        /// <param name="name">Fully qualified name of the property to take action on. We insist on qualifying the property fully like 'System.Fabric.Chaos.DataStructures.ChaosParameters.MaxConcurrentFaults' so that in the property graph we know exactly which property we are targetting.</param>
        /// <param name="value">Value of the target property</param>
        /// <param name="mode">If 'Update' updates the target property with 'value', if 'Verify' checks if the target property has 'value'</param>
        public static void VisitObject(object obj, string name, string value, ObjectVisitMode mode)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
            {
                return;
            }

            Helper(obj, name, value, mode, new HashSet <string>(StringComparer.Ordinal));
        }
Beispiel #2
0
        /// <summary>
        /// Recursively visits through the properties of the object and based on mode takes appropriate action.
        /// </summary>
        /// <param name="obj">Object to visit</param>
        /// <param name="name">Fully qualified name of the property to take action on. We insist on qualifying the property fully like 'System.Fabric.Chaos.DataStructures.ChaosParameters.MaxConcurrentFaults' so that in the property graph we know exactly which property we are targetting.</param>
        /// <param name="value">Value of the target property</param>
        /// <param name="mode">If 'Update' updates the target property with 'value', if 'Verify' checks if the target property has 'value'</param>
        /// <param name="visited">To avoid cycles, contains the names of the properties that have already been visited and if encountered again avoids digging deeper.</param>
        private static void Helper(object obj, string name, string value, ObjectVisitMode mode, HashSet <string> visited)
        {
            if (obj == null)
            {
                return;
            }

            Type objType = obj.GetType();

            PropertyInfo[] properties = objType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            object propValue = null;

            // Check if any property of obj matches the provided 'name'
            foreach (PropertyInfo property in properties)
            {
                string propertyFullName = objType.FullName + "." + property.Name;

                if (visited.Contains(propertyFullName))
                {
                    continue;
                }

                if (MatchSuffix(propertyFullName, name))
                {
                    // Handle list type property
                    if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(List <>))
                    {
                        Type listItemType = property.PropertyType.GetGenericArguments()[0];
                        if (listItemType == null)
                        {
                            return;
                        }

                        var resultList = CreateList(listItemType);

                        var inputlist = GetList(listItemType, value, ListElementSeparator);

                        switch (mode)
                        {
                        case ObjectVisitMode.Update:

                            foreach (var item in inputlist)
                            {
                                resultList.Add(item);
                            }

                            property.SetValue(obj, resultList, null);
                            break;

                        case ObjectVisitMode.Verify:

                            IList propertyValue = property.GetValue(obj, null) as IList;

                            if (propertyValue == null || propertyValue.Count != inputlist.Count)
                            {
                                throw new InvalidOperationException("propertyValue should have been a list of the same size as value.");
                            }

                            for (int i = 0; i < inputlist.Count; ++i)
                            {
                                if (!inputlist[i].Equals(propertyValue[i]))
                                {
                                    throw new InvalidOperationException("property does not have the expected value.");
                                }
                            }

                            break;
                        }
                    }
                    else if (property.PropertyType.GetInterface(IEnumerableInterfaceName) == null) // not a collection type
                    {
                        object inputValue = Convert.ChangeType(value, property.PropertyType);
                        propValue = property.GetValue(obj, null);

                        switch (mode)
                        {
                        case ObjectVisitMode.Update:

                            property.SetValue(obj, inputValue, null);
                            break;

                        case ObjectVisitMode.Verify:

                            if (!propValue.Equals(inputValue))
                            {
                                throw new InvalidOperationException("property does not have the expected value.");
                            }

                            break;
                        }
                    }

                    return;
                }

                try
                {
                    visited.Add(propertyFullName);

                    propValue = property.GetValue(obj, null);
                    if (property.PropertyType.Assembly == objType.Assembly)
                    {
                        Helper(propValue, name, value, mode, visited);
                    }
                }
                catch (TargetParameterCountException)
                {
                    if (!property.GetIndexParameters().Any())
                    {
                        throw;
                    }
                }
            }
        }