private static object InvokeReturnParameterlessMethod(Type type, object obj, string name)
        {
            IFunctionCallback <object, object> methodActivator = ReflectionUtils.CreateReturnParameterlessMethodCallback(type, type.GetMethod(name));

            return(methodActivator.Invoke(obj));
        }
Esempio n. 2
0
            /// <summary>
            /// Creates a new writer for the <see cref="ICollection"></see>.
            /// </summary>
            /// <param name="formatter"> The formatter. </param>
            /// <param name="enumerable"> The collection. </param>
            public CollectionWriter(AbstractFormatter formatter, IEnumerable enumerable)
            {
                // Gets type and generic type definition of the collection

                Type collectionType = enumerable.GetType();
                Type elementType    = collectionType.GetGenericArguments()[0];
                Type collectionGTD  = collectionType.GetGenericTypeDefinition();

                // Gets the methods of the collection

                MethodInfo methodInfo = null;

                MethodInfo[] methodsInfo = collectionType.GetMethods(BindingFlags.Instance | BindingFlags.Public);

                Func <string, Action <object> > getCallbackReturnMethod = (name) =>
                {
                    // Builds a callback for the public method with specified name
                    // (one parameter, return something)

                    Func <MethodInfo, bool> predicate = (m) =>
                    {
                        if (m.Name != name || m.ReturnType == voidType)
                        {
                            return(false);
                        }

                        ParameterInfo[] parameters = m.GetParameters();
                        return(parameters.Length == 1 && parameters[0].ParameterType.IsBaseTypeOrEquals(elementType));
                    };

                    methodInfo = methodsInfo.FindOrDefault(predicate);
                    IFunctionCallback <object, object, object> callback = formatter.CreateReturnOneParameterMethodCallback(collectionType, methodInfo);
                    return((o) => callback.Invoke(enumerable, o));
                };

                Func <string, Action <object> > getCallbackReturnlessMethod = (name) =>
                {
                    // Builds a callback for the public method with specified name
                    // (one parameter, returnless)

                    Func <MethodInfo, bool> predicate = (m) =>
                    {
                        if (m.Name != name || m.ReturnType != voidType)
                        {
                            return(false);
                        }

                        ParameterInfo[] parameters = m.GetParameters();
                        return(parameters.Length == 1 && parameters[0].ParameterType.IsBaseTypeOrEquals(elementType));
                    };

                    methodInfo = methodsInfo.FindOrDefault(predicate);
                    IActionCallback <object, object> callback = formatter.CreateReturnlessOneParameterMethodCallback(collectionType, methodInfo);
                    return((o) => callback.Invoke(enumerable, o));
                };

                // Finds the specific methods for the adding a new values of the different collections

                if (collectionGTD == linkedListType)
                {
                    // Linked list
                    this.collectionAddAction = getCallbackReturnMethod("AddLast");
                }

                if (collectionGTD == listType)
                {
                    // List
                    IList list = enumerable as IList;
                    this.collectionAddAction = (o) => list.Add(o);
                }

                if (collectionGTD == hashSetType || collectionGTD == sortedSetType)
                {
                    // Hash set, sorted set
                    this.collectionAddAction = getCallbackReturnMethod("Add");
                }

                if (collectionGTD == concurrentBagType)
                {
                    // Concurrent bag
                    this.collectionAddAction = getCallbackReturnlessMethod("Add");
                }

                if (collectionGTD == queueType || collectionGTD == concurrentQueueType)
                {
                    // Queue, concurrent queue
                    this.collectionAddAction = getCallbackReturnlessMethod("Enqueue");
                }

                if (collectionGTD == stackType || collectionGTD == concurrentStackType)
                {
                    // Stack, concurrent stack
                    this.collectionAddAction = getCallbackReturnlessMethod("Push");
                    this.collectionIsStack   = true;
                }

                // Saves the callback for the found method

                if (this.collectionIsStack)
                {
                    this.addAction = (v) => collectedValues.AddFirst(v);
                }
                else
                {
                    this.addAction = this.collectionAddAction;
                }
            }
Esempio n. 3
0
        /// <summary>
        /// Builds a target type that based on declared type that is associated with the current type.
        /// </summary>
        /// <param name="declaredType"> Declared type. </param>
        private void BuildType(Type declaredType)
        {
            Type createdType = null;

            if (!this.createdTypes.TryGetValue(declaredType, out createdType))
            {
                // Creates a new type

                createdType = (this.isGenericTypeDefinition) ? this.hostType.MakeGenericType(declaredType.GetGenericArguments()) : this.hostType;

                // Creates an activator for the created type

                IFunctionCallback <object> factoryMethod = ReflectionUtils.CreateInstance(createdType);

                // Creates the callbacks for the get/set accessors of the fields

                KeyAttribute     keyAttribute;
                FormattableValue value;
                LinkedList <FormattableValue>      loadedValues = new LinkedList <FormattableValue>();
                IFunctionCallback <object, object> getAccessor  = null;
                IActionCallback <object, object>   setAccessor  = null;

                FieldInfo[] fields       = createdType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
                int         fieldsLength = fields.Length;
                FieldInfo   field        = null;

                for (int i = 0; i < fieldsLength; i++)
                {
                    field        = fields[i];
                    keyAttribute = field.GetAttribute <KeyAttribute>(true);

                    if (keyAttribute != null)
                    {
                        getAccessor = ReflectionUtils.CreateGetAccessor(createdType, field);
                        setAccessor = ReflectionUtils.CreateSetAccessor(createdType, field);

                        value = new FormattableValue(
                            keyAttribute.Name,
                            keyAttribute.Optional,
                            keyAttribute.Order,
                            field.FieldType,
                            getAccessor,
                            setAccessor
                            );

                        loadedValues.AddLast(value);
                    }
                }

                // Action that used for getting the key attribute and property info of the overridden properties

                PropertyInfo property          = null;
                MethodInfo   propertyGetMethod = null;
                Type         baseType          = null;

                Action <Type, string> getPropertyKeyAttributeFromBase = null;
                getPropertyKeyAttributeFromBase = (t, n) =>
                {
                    baseType = t.BaseType;
                    if (baseType == null)
                    {
                        return;
                    }

                    property = baseType.GetProperty(n, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

                    if (property != null)
                    {
                        keyAttribute = property.GetAttribute <KeyAttribute>(true);
                        if (keyAttribute == null)
                        {
                            propertyGetMethod = property.GetGetMethod(true);
                            if (propertyGetMethod == null || propertyGetMethod.GetBaseDefinition() != propertyGetMethod)
                            {
                                // Property is overridden - tests the properties of the base type
                                getPropertyKeyAttributeFromBase(baseType, n);
                            }
                        }
                    }
                    else
                    {
                        // Required property isn't exists in the type - tests the properties of the base type
                        getPropertyKeyAttributeFromBase(baseType, n);
                    }
                };

                // Creates the callbacks for the get/set accessors of the properties

                PropertyInfo[] properties       = createdType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
                int            propertiesLength = properties.Length;

                for (int i = 0; i < propertiesLength; i++)
                {
                    property     = properties[i];
                    keyAttribute = property.GetAttribute <KeyAttribute>(true);

                    if (keyAttribute == null)
                    {
                        propertyGetMethod = property.GetGetMethod(true);
                        if (propertyGetMethod == null || propertyGetMethod.GetBaseDefinition() != propertyGetMethod)
                        {
                            // Property is overridden - tests the properties of the base type

                            getPropertyKeyAttributeFromBase(createdType, property.Name);
                        }
                    }

                    if (keyAttribute == null || property.GetIndexParameters().Length != 0)
                    {
                        continue;
                    }

                    getAccessor = ReflectionUtils.CreateGetAccessor(createdType, property);
                    setAccessor = ReflectionUtils.CreateSetAccessor(createdType, property);

                    value = new FormattableValue(
                        keyAttribute.Name,
                        keyAttribute.Optional,
                        keyAttribute.Order,
                        property.PropertyType,
                        getAccessor,
                        setAccessor
                        );

                    loadedValues.AddLast(value);
                }

                // Sorts the values by order

                FormattableValue[] sortedValues = loadedValues.ToArray();
                SortUtils.QuickSort(true, sortedValues);

                // Saves the factory method, sorted values and created type

                this.factoryMethods.Add(declaredType, factoryMethod);
                this.values.Add(declaredType, sortedValues);
                this.createdTypes.Add(declaredType, createdType);
            }
        }
Esempio n. 4
0
        private static object GetFieldValue(Type type, object obj, string name)
        {
            IFunctionCallback <object, object> getAccessor = ReflectionUtils.CreateGetAccessor(type, type.GetField(name));

            return(getAccessor.Invoke(obj));
        }