/// <summary>
        /// Returns true if this code generator can generate a member for the
        /// specified source property type.
        /// </summary>
        /// <remarks>The base method checks for DataContract serializability. If derived classes
        /// override, they must be able to generate additional properties in
        /// <see cref="GenerateNonSerializableProperty" />.</remarks>
        /// <param name="propertyDescriptor">The source property.</param>
        /// <returns>true if this code generator should/can generate a member for the Type.</returns>
        protected virtual bool CanGenerateProperty(PropertyDescriptor propertyDescriptor)
        {
            Type type = propertyDescriptor.PropertyType;

            // Make sure the member is serializable (based on data contract attributes, [Exclude], type support, etc.).
            if (SerializationUtility.IsSerializableDataMember(propertyDescriptor))
            {
                // If property type is an enum that cannot be generated, we cannot expose this property, but only log a warning
                string errorMessage = null;
                Type   enumType     = TypeUtility.GetNonNullableType(type);
                if (enumType.IsEnum)
                {
                    if (!this.ClientProxyGenerator.CanExposeEnumType(enumType, out errorMessage))
                    {
                        this.ClientProxyGenerator.LogWarning(String.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Property_Enum_Error, this.Type, propertyDescriptor.Name, enumType.FullName, errorMessage));
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #2
0
            private bool IsVisible(PropertyDescriptor pd)
            {
                if (SerializationUtility.IsSerializableDataMember(pd))
                {
                    return(true);
                }

                // Even if this property doesn't have [Include], we consider this property to
                // be visible when its type is a known entity type, as it implies that there
                // was a query operation for it.
                Type associatedEntityType = TypeUtility.GetElementType(pd.PropertyType);

                if (associatedEntityType != null && this.domainServiceDescription.EntityTypes.Contains(associatedEntityType))
                {
                    return(true);
                }

                if (TypeUtility.FindIEnumerable(pd.ComponentType) != null)
                {
                    // REVIEW: Find a better way to deal with this...
                    if (pd.Name.Equals("Count", StringComparison.Ordinal))
                    {
                        return(true);
                    }
                }

                return(false);
            }
Example #3
0
        /// <summary>
        /// Returns true if the specified property is a data member that should be serialized
        /// </summary>
        /// <param name="propertyDescriptor">The property to inspect</param>
        /// <returns>true if the specified property is a data member that should be serialized</returns>
        internal static bool IsSerializableDataMember(PropertyDescriptor propertyDescriptor)
        {
            bool serializable = SerializationUtility.IsSerializableDataMember(propertyDescriptor);

            Debug.Assert(!TypeUtils.IsKeyProperty(propertyDescriptor) || serializable, "Key property must be serializable.");
            Debug.Assert(!TypeUtils.IsAssociation(propertyDescriptor) || !serializable, "Association property should not be serializable.");
            Debug.Assert(!TypeUtils.IsComposition(propertyDescriptor) || !serializable, "Composition property should not be serializable.");
            Debug.Assert(!TypeUtils.IsExternalReference(propertyDescriptor) || !serializable, "External Reference property should not be serializable.");
            Debug.Assert(!TypeUtils.IsExcluded(propertyDescriptor) || !serializable, "Excluded property should not be serializable.");

            return(serializable);
        }
        private static void EmitProperties(TypeBuilder typeBuilder, Type type, Type parentSurrogateType, FieldInfo wrapperField, Lazy <ILGenerator> typeInitializerGenerator)
        {
            bool hasParent = (parentSurrogateType != typeof(object));

            // Create fields for each of the properties.
            foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(type))
            {
                // Skip properties inherited from a base class.
                // We allow "holes" in the visible entity hierarchy (i.e. some entity types are not exposed
                // via the DomainService and hence do not appear in the list of known entity types).
                // Properties appearing in unexposed entities are lifted to the first visible subclass.
                // So if our parent surrogate does not declare a property, it means we have discovered
                // a hole in the visible hierarchy and must lift that property.
                if (hasParent && pd.ComponentType != type && parentSurrogateType.GetProperty(pd.Name) != null)
                {
                    continue;
                }

                if (SerializationUtility.IsSerializableDataMember(pd))
                {
                    DataContractSurrogateGenerator.EmitProperty(typeBuilder, wrapperField, typeInitializerGenerator, pd, pd.Name);
                }
            }
        }
        /// <summary>
        /// Validates that the user type implements the <see cref="IUser"/> interface naturally for use
        /// in codegen.
        /// </summary>
        /// <remarks>
        /// This check ensures no part of the interface was implemented explicitly and the <c>Name</c>
        /// property was marked as a <c>[Key]</c>.
        /// </remarks>
        /// <param name="user">The type that implemented the <see cref="IUser"/> interface.</param>
        /// <exception cref="InvalidOperationException"> is thrown if the <see cref="IUser"/> interface
        /// is not correctly implemented.
        /// </exception>
        private static void CheckIUser(Type user)
        {
            bool implementsName  = false;
            bool implementsRoles = false;

            System.Diagnostics.Debug.Assert(typeof(IUser).IsAssignableFrom(user),
                                            "user should always be of type IUser.");

            foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(user))
            {
                switch (property.Name)
                {
                case "Name":
                {
                    // [Key]
                    // public string Name { get; set; }
                    if (typeof(string) != property.PropertyType)
                    {
                        break;
                    }
                    if (!SerializationUtility.IsSerializableDataMember(property))
                    {
                        throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InstalledUICulture,
                                                                Resources.ApplicationServices_MustBeSerializable,
                                                                property.Name, user.Name));
                    }
                    if (property.Attributes[typeof(KeyAttribute)] == null)
                    {
                        throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InstalledUICulture,
                                                                Resources.ApplicationServices_NameMustBeAKey,
                                                                user.Name));
                    }
                    PropertyInfo namePropertyInfo = user.GetProperty("Name");
                    if ((namePropertyInfo != null) && (namePropertyInfo.GetSetMethod() == null))
                    {
                        break;
                    }
                    implementsName = true;
                    break;
                }

                case "Roles":
                {
                    // public IEnumerable<string> Roles { get; set; }
                    if (!typeof(IEnumerable <string>).IsAssignableFrom(property.PropertyType))
                    {
                        break;
                    }
                    if (!SerializationUtility.IsSerializableDataMember(property))
                    {
                        throw new InvalidOperationException(string.Format(
                                                                CultureInfo.InstalledUICulture,
                                                                Resources.ApplicationServices_MustBeSerializable,
                                                                property.Name, user.Name));
                    }
                    PropertyInfo rolesPropertyInfo = user.GetProperty("Roles");
                    if ((rolesPropertyInfo != null) && (rolesPropertyInfo.GetSetMethod() == null))
                    {
                        break;
                    }
                    implementsRoles = true;
                    break;
                }

                default:
                    break;
                }
            }

            if (!implementsName || !implementsRoles)
            {
                throw new InvalidOperationException(string.Format(
                                                        CultureInfo.InstalledUICulture,
                                                        Resources.ApplicationServices_MustBeIUser,
                                                        user.Name));
            }
        }