/// <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); } }
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); }
/// <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)); } }