Esempio n. 1
0
        /// <summary>Gets a delegate that can be invoked to add an item to a collection of the specified type.</summary>
        /// <param name='listType'>Type of list to use.</param>
        /// <returns>The delegate to invoke.</returns>
        internal static Action <object, object> GetAddToCollectionDelegate(Type listType)
        {
            Debug.Assert(listType != null, "listType != null");

            Type                listElementType;
            MethodInfo          addMethod = ClientTypeUtil.GetAddToCollectionMethod(listType, out listElementType);
            ParameterExpression list      = Expression.Parameter(typeof(object), "list");
            ParameterExpression item      = Expression.Parameter(typeof(object), "element");
            Expression          body      = Expression.Call(Expression.Convert(list, listType), addMethod, Expression.Convert(item, listElementType));
            LambdaExpression    lambda    = Expression.Lambda(body, list, item);

            return((Action <object, object>)lambda.Compile());
        }
Esempio n. 2
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="edmProperty">Back reference to the EdmProperty this annotation is part of.</param>
        /// <param name="propertyInfo">propertyInfo instance.</param>
        /// <param name="model">The client model.</param>
        internal ClientPropertyAnnotation(IEdmProperty edmProperty, PropertyInfo propertyInfo, ClientEdmModel model)
        {
            Debug.Assert(edmProperty != null, "edmProperty != null");
            Debug.Assert(propertyInfo != null, "null propertyInfo");

            // Property should always have DeclaringType
            Debug.Assert(propertyInfo.DeclaringType != null, "Property without a declaring type");

            this.EdmProperty          = edmProperty;
            this.PropertyName         = ClientTypeUtil.GetServerDefinedName(propertyInfo);
            this.NullablePropertyType = propertyInfo.PropertyType;
            this.PropertyType         = Nullable.GetUnderlyingType(this.NullablePropertyType) ?? this.NullablePropertyType;
            this.DeclaringClrType     = propertyInfo.DeclaringType;

            MethodInfo propertyGetMethod = propertyInfo.GetGetMethod();
            MethodInfo propertySetMethod = propertyInfo.GetSetMethod();

            ParameterExpression instance = Expression.Parameter(typeof(Object), "instance");
            ParameterExpression value    = Expression.Parameter(typeof(Object), "value");

            // instance => (Object)(((T)instance).get_PropertyName());  <-- we need to box the value back to object to return
            this.propertyGetter = propertyGetMethod == null ? null : (Func <object, object>)Expression.Lambda(
                Expression.Convert(
                    Expression.Call(
                        Expression.Convert(instance, this.DeclaringClrType),
                        propertyGetMethod),
                    typeof(Object)),
                instance).Compile();

            // (instance, value) => ((T)instance).set_PropertyName((T1)value);
            this.propertySetter = propertySetMethod == null ? null : (Action <object, object>)Expression.Lambda(
                Expression.Call(
                    Expression.Convert(instance, this.DeclaringClrType),
                    propertySetMethod,
                    Expression.Convert(value, this.NullablePropertyType)),
                instance,
                value).Compile();

            this.Model = model;

            this.IsKnownType = PrimitiveType.IsKnownType(this.PropertyType);

            // non primitive types: dictionary/collections
            if (!this.IsKnownType)
            {
                var setMethodInfo = ClientTypeUtil.GetMethodForGenericType(this.PropertyType, typeof(IDictionary <,>), "set_Item", out this.DictionaryValueType);

                if (setMethodInfo != null)
                {
                    ParameterExpression propertyNameParam = Expression.Parameter(typeof(String), "propertyName");

                    // (instance, propertyName, value) => ((IDictionary<string, DictionaryValueType>)instance)[propertyName] = (DictionaryValueType)value;
                    this.dictionarySetter = (Action <Object, String, Object>)Expression.Lambda(
                        Expression.Call(
                            Expression.Convert(instance, typeof(IDictionary <,>).MakeGenericType(typeof(String), this.DictionaryValueType)),
                            setMethodInfo,
                            propertyNameParam,
                            Expression.Convert(value, this.DictionaryValueType)),
                        instance,
                        propertyNameParam,
                        value).Compile();
                }
                else
                {
                    var containsMethod = ClientTypeUtil.GetMethodForGenericType(this.PropertyType, typeof(ICollection <>), "Contains", out this.collectionGenericType);
                    var addMethod      = ClientTypeUtil.GetAddToCollectionMethod(this.PropertyType, out this.collectionGenericType);
                    var removeMethod   = ClientTypeUtil.GetMethodForGenericType(this.PropertyType, typeof(ICollection <>), "Remove", out this.collectionGenericType);
                    var clearMethod    = ClientTypeUtil.GetMethodForGenericType(this.PropertyType, typeof(ICollection <>), "Clear", out this.collectionGenericType);

                    // (instance, value) => ((PropertyType)instance).Contains((CollectionType)value);  returns boolean
                    this.collectionContains = containsMethod == null ? null : (Func <Object, Object, Boolean>)Expression.Lambda(
                        Expression.Call(
                            Expression.Convert(instance, this.PropertyType),
                            containsMethod,
                            Expression.Convert(value, this.collectionGenericType)),
                        instance,
                        value).Compile();

                    // (instance, value) => ((PropertyType)instance).Add((CollectionType)value);
                    this.collectionAdd = addMethod == null ? null : (Action <Object, Object>)Expression.Lambda(
                        Expression.Call(
                            Expression.Convert(instance, this.PropertyType),
                            addMethod,
                            Expression.Convert(value, this.collectionGenericType)),
                        instance,
                        value).Compile();

                    // (instance, value) => ((PropertyType)instance).Remove((CollectionType)value);  returns boolean
                    this.collectionRemove = removeMethod == null ? null : (Func <Object, Object, Boolean>)Expression.Lambda(
                        Expression.Call(
                            Expression.Convert(instance, this.PropertyType),
                            removeMethod,
                            Expression.Convert(value, this.collectionGenericType)),
                        instance,
                        value).Compile();

                    // (instance) => ((PropertyType)instance).Clear();
                    this.collectionClear = clearMethod == null ? null : (Action <Object>)Expression.Lambda(
                        Expression.Call(
                            Expression.Convert(instance, this.PropertyType),
                            clearMethod),
                        instance).Compile();
                }
            }

            Debug.Assert(this.collectionGenericType == null || this.DictionaryValueType == null, "collectionGenericType and DictionaryItemType mutually exclusive. (They both can be null though).");
        }