예제 #1
0
 private static void AddValue(XElement element, DynamicElement item)
 {
     if (!element.HasElements && !string.IsNullOrEmpty(element.Value))
     {
         item["Value"] = element.Value;
     }
 }
예제 #2
0
        private static Array BindArray(Array source, DynamicElement config)
        {
            var children    = config.GetChildren2().ToArray();
            var arrayLength = source.Length;
            var elementType = source.GetType().GetElementType();
            var newArray    = Array.CreateInstance(elementType, arrayLength + children.Length);

            // binding to array has to preserve already initialized arrays with values
            if (arrayLength > 0)
            {
                Array.Copy(source, newArray, arrayLength);
            }

            for (int i = 0; i < children.Length; i++)
            {
                try
                {
                    var item = BindInstance(
                        type: elementType,
                        instance: null,
                        element: children[i]);
                    if (item != null)
                    {
                        newArray.SetValue(item, arrayLength + i);
                    }
                }
                catch
                {
                }
            }

            return(newArray);
        }
예제 #3
0
        private static void BindProperty(PropertyInfo property, object instance, DynamicElement element)
        {
            // We don't support set only, non public, or indexer properties
            if (property.GetMethod == null ||
                !property.GetMethod.IsPublic ||
                property.GetMethod.GetParameters().Length > 0)
            {
                return;
            }

            var propertyValue   = property.GetValue(instance);
            var hasPublicSetter = property.SetMethod != null && property.SetMethod.IsPublic;

            if (propertyValue == null && !hasPublicSetter)
            {
                // Property doesn't have a value and we cannot set it so there is no
                // point in going further down the graph
                return;
            }

            //propertyValue = BindInstance(property.PropertyType, propertyValue, element.GetSection(property.Name));
            propertyValue = BindInstance(property.PropertyType, propertyValue, element[property.Name]); //TODO
            if (propertyValue != null && hasPublicSetter)
            {
                property.SetValue(instance, propertyValue);
            }
        }
예제 #4
0
        private static void BindCollection(object collection, Type collectionType, DynamicElement config)
        {
            var typeInfo = collectionType.GetTypeInfo();

            // ICollection<T> is guaranteed to have exacly one parameter
            var itemType  = typeInfo.GenericTypeArguments[0];
            var addMethod = typeInfo.GetDeclaredMethod("Add");

            foreach (var section in config.GetChildren2())
            {
                try
                {
                    var item = BindInstance(
                        type: itemType,
                        instance: null,
                        element: section);
                    if (item != null)
                    {
                        addMethod.Invoke(collection, new[] { item });
                    }
                }
                catch
                {
                }
            }
        }
예제 #5
0
        private static void BindDictionary(object dictionary, Type dictionaryType, DynamicElement config)
        {
            var typeInfo = dictionaryType.GetTypeInfo();

            // IDictionary<K,V> is guaranteed to have exactly two parameters
            var keyType   = typeInfo.GenericTypeArguments[0];
            var valueType = typeInfo.GenericTypeArguments[1];

            if (keyType != typeof(string))
            {
                // We only support string keys
                return;
            }

            var addMethod = typeInfo.GetDeclaredMethod("Add");

            foreach (var child in config.GetChildren2())
            {
                var item = BindInstance(
                    type: valueType,
                    instance: null,
                    element: child);
                if (item != null)
                {
                    //var key = child.Key;
                    var key = string.Empty; //TODO
                    addMethod.Invoke(dictionary, new[] { key, item });
                }
            }
        }
예제 #6
0
 private static void AddAttributes(XElement element, DynamicElement item)
 {
     if (element.Attributes().Any())
     {
         foreach (var attribute in element.Attributes())
         {
             item[attribute.Name.LocalName] = attribute.Value;
         }
     }
 }
예제 #7
0
        public static dynamic ToDynamic(this XElement element)
        {
            var item = new DynamicElement();

            AddChildren(element, item);
            AddAttributes(element, item);
            AddValue(element, item);

            return(item);
        }
예제 #8
0
 private static void BindNonScalar(this DynamicElement element, object instance)
 {
     if (instance != null)
     {
         foreach (var property in GetAllProperties(instance.GetType().GetTypeInfo()))
         {
             BindProperty(property, instance, element);
         }
     }
 }
예제 #9
0
        public static T Bind <T>(this DynamicElement element, T defaultValue)
        {
            var value = element.Bind(typeof(T));

            if (value == null)
            {
                return(defaultValue);
            }

            return((T)value);
        }
예제 #10
0
        public static object Bind(this DynamicElement element, Type type)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            return(BindInstance(
                       type: type,
                       instance: null,
                       element: element));
        }
예제 #11
0
        private static object BindInstance(Type type, object instance, DynamicElement element)
        {
            var section     = element;
            var configValue = section?["Value"]; //TODO

            if (configValue != null)
            {
                // Leaf nodes are always reinitialized
                return(ReadValue(type, configValue, section));
            }

            if (element != null && element.GetChildren().Any())
            {
                if (instance == null)
                {
                    instance = CreateInstance(type);
                }

                // See if its a Dictionary
                var collectionInterface = FindOpenGenericInterface(typeof(IDictionary <,>), type);
                if (collectionInterface != null)
                {
                    BindDictionary(instance, collectionInterface, element);
                }
                else if (type.IsArray)
                {
                    instance = BindArray((Array)instance, element);
                }
                else
                {
                    // See if its an ICollection
                    collectionInterface = FindOpenGenericInterface(typeof(ICollection <>), type);
                    if (collectionInterface != null)
                    {
                        BindCollection(instance, collectionInterface, element);
                    }
                    // Something else
                    else
                    {
                        BindNonScalar(element, instance);
                    }
                }
            }

            return(instance);
        }
예제 #12
0
        private static object ReadValue(Type type, string value, DynamicElement element)
        {
            if (type.GetTypeInfo().IsGenericType&& type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                return(ReadValue(Nullable.GetUnderlyingType(type), value, element));
            }

            try
            {
                //return TypeDescriptor.GetConverter(type).ConvertFromInvariantString(element.Value);
                return(TypeDescriptor.GetConverter(type).ConvertFromInvariantString(element["Value"])); //TODO
            }
            catch (Exception ex)
            {
                //throw new InvalidOperationException(Resources.FormatError_FailedBinding(element.Value, type), ex);
                throw new InvalidOperationException(Resources.FormatError_FailedBinding(element["Value"], type), ex); //TODO
            }
        }
예제 #13
0
        private static void AddChildren(XElement element, DynamicElement item)
        {
            if (element.HasElements)
            {
                var uniqueElements   = element.Elements().Where(el => element.Elements().Count(el2 => el2.Name.LocalName.Equals(el.Name.LocalName)) == 1).ToList();
                var repeatedElements = element.Elements().Except(uniqueElements);

                foreach (var repeatedElementGroup in repeatedElements.GroupBy(re => re.Name.LocalName).OrderBy(el => el.Key))
                {
                    var list = new List <dynamic>();
                    foreach (var repeatedElement in repeatedElementGroup)
                    {
                        list.Add(ToDynamic(repeatedElement));
                    }

                    item[PluralizationService.Pluralize(repeatedElementGroup.Key)] = list;
                }

                foreach (var uniqueElement in uniqueElements.OrderBy(el => el.Name.LocalName))
                {
                    item[uniqueElement.Name.LocalName] = ToDynamic(uniqueElement);
                }
            }
        }
예제 #14
0
        private static IDictionary <string, dynamic> GetChildren(this DynamicElement element)
        {
            var list = element.Properties.Where(p => typeof(DynamicElement) == p.Value.GetType() || typeof(List <dynamic>) == p.Value.GetType()).ToDictionary(e => e.Key, e => e.Value);

            return(list);
        }
예제 #15
0
 private static IEnumerable <DynamicElement> GetChildren2(this DynamicElement element)
 {
     return(new DynamicElement[] {});
 }
예제 #16
0
 public static T Bind <T>(this DynamicElement element)
 {
     return(element.Bind(default(T)));
 }