// PUBLIC METHODS /////////////////////////////////////////////////// #region Extension Methods /// <summary>Adds a property on the API object type by the given CLR property that represents the API property.</summary> /// <param name="clrPropertyName">The CLR name of the CLR property.</param> /// <param name="clrPropertyType">The CLR type of CLR property.</param> /// <returns>A fluent-style builder for the API object type.</returns> public static IApiObjectTypeBuilder ApiProperty(this IApiObjectTypeBuilder apiObjectTypeBuilder, string clrPropertyName, Type clrPropertyType) { Contract.Requires(clrPropertyName.SafeHasContent()); Contract.Requires(clrPropertyType != null); return(apiObjectTypeBuilder.ApiProperty(clrPropertyName, clrPropertyType, null)); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiObjectTypeConvention Implementation public void Apply(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiObjectTypeBuilder != null); // Try and discover the identity CLR property of the CLR object type: var clrObjectType = apiObjectTypeBuilder.ClrType; var clrProperties = ClrPropertyDiscoveryRules.GetClrProperties(clrObjectType); // 1. By convention, any CLR property named "Id" is the identity CLR property for this CLR object type. var clrIdProperty = ClrPropertyDiscoveryRules.GetClrPropertyByName(clrProperties, "Id"); if (clrIdProperty != null) { // Call ApiIdentity method on the discovered CLR property. var clrIdPropertyName = clrIdProperty.Name; var clrIdPropertyType = clrIdProperty.PropertyType; apiObjectTypeBuilder.ApiIdentity(clrIdPropertyName, clrIdPropertyType); return; } // 2. By convention, any CLR property named "XXXId" where XXX is the CLR class name is the identity CLR property for this CLR object type. var clrClassName = clrObjectType.Name; var clrClassNameAndId = $"{clrClassName}Id"; var clrClassNameAndIdProperty = ClrPropertyDiscoveryRules.GetClrPropertyByName(clrProperties, clrClassNameAndId); // ReSharper disable once InvertIf if (clrClassNameAndIdProperty != null) { // Call ApiIdentity method on the discovered CLR property. var clrClassNameAndIdPropertyName = clrClassNameAndIdProperty.Name; var clrClassNameAndIdPropertyType = clrClassNameAndIdProperty.PropertyType; apiObjectTypeBuilder.ApiIdentity(clrClassNameAndIdPropertyName, clrClassNameAndIdPropertyType); } }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiObjectTypeConvention Implementation public void Apply(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiObjectTypeBuilder != null); // Call ApiProperty method on all the discoverable CLR properties for the given CLR object type. var clrObjectType = apiObjectTypeBuilder.ClrType; var clrProperties = ClrPropertyDiscoveryRules.GetClrProperties(clrObjectType); foreach (var clrProperty in clrProperties) { var clrPropertyName = clrProperty.Name; var clrPropertyType = clrProperty.PropertyType; apiObjectTypeBuilder.ApiProperty(clrPropertyName, clrPropertyType); } }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiObjectTypeConvention Implementation public void Apply(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiObjectTypeBuilder != null); var clrObjectType = apiObjectTypeBuilder.ClrType; var clrPropertyInfoCollection = ClrPropertyDiscoveryRules.GetClrProperties(clrObjectType); var apiObjectTypeConfiguration = (ApiObjectTypeConfiguration)apiObjectTypeBuilder; var apiPrecedenceStack = apiObjectTypeConfiguration.ApiPrecedenceStack; foreach (var clrPropertyInfo in clrPropertyInfoCollection) { HandleApiPropertyAttribute(apiObjectTypeBuilder, apiPrecedenceStack, clrPropertyInfo); HandleApiIdentityAttribute(apiObjectTypeBuilder, apiPrecedenceStack, clrPropertyInfo); HandleApiRelationshipAttribute(apiObjectTypeBuilder, apiPrecedenceStack, clrPropertyInfo); } }
private static void HandleApiRelationshipAttribute(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiPrecedenceStack apiPrecedenceStack, PropertyInfo clrPropertyInfo) { Contract.Requires(apiObjectTypeBuilder != null); Contract.Requires(clrPropertyInfo != null); var apiRelationshipAttribute = Attribute.GetCustomAttribute(clrPropertyInfo, typeof(ApiRelationshipAttribute)); if (apiRelationshipAttribute == null) { return; } var clrPropertyName = clrPropertyInfo.Name; var clrPropertyType = clrPropertyInfo.PropertyType; apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiObjectTypeBuilder.ApiRelationship(clrPropertyName, clrPropertyType); apiPrecedenceStack.Pop(); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiObjectTypeConvention Implementation public void Apply(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiObjectTypeBuilder != null); // Try and discover relationship CLR properties of the CLR object type: var clrObjectType = apiObjectTypeBuilder.ClrType; var clrProperties = ClrPropertyDiscoveryRules.GetClrProperties(clrObjectType); foreach (var clrProperty in clrProperties) { var clrPropertyType = clrProperty.PropertyType; var apiTypeKind = clrPropertyType.GetApiTypeKind(out var clrItemType); switch (apiTypeKind) { case ApiTypeKind.Collection: { var apiItemTypeKind = clrItemType.GetApiTypeKind(); switch (apiItemTypeKind) { case ApiTypeKind.Object: { var clrPropertyName = clrProperty.Name; apiObjectTypeBuilder.ApiRelationship(clrPropertyName, clrPropertyType); break; } } break; } case ApiTypeKind.Object: { var clrPropertyName = clrProperty.Name; apiObjectTypeBuilder.ApiRelationship(clrPropertyName, clrPropertyType); break; } } } }
public void Apply(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiConventionSettings apiConventionSettings) { apiObjectTypeBuilder.HasDescription(null); }
/// <summary>Adds a property on the API object type by selecting the CLR property that represents the API property.</summary> /// <typeparam name="TObject">The CLR object type associated to the API object type for CLR serializing/deserializing purposes.</typeparam> /// <typeparam name="TProperty">The CLR type of property selected on the CLR object type.</typeparam> /// <param name="clrPropertySelector">Expression that selects the CLR property on the CLR object type.</param> /// <returns>A fluent-style builder for the API object type.</returns> public static IApiObjectTypeBuilder <TObject> ApiProperty <TObject, TProperty>(this IApiObjectTypeBuilder <TObject> apiObjectTypeBuilder, Expression <Func <TObject, TProperty> > clrPropertySelector) { Contract.Requires(clrPropertySelector != null); return(apiObjectTypeBuilder.ApiProperty(clrPropertySelector, null)); }
// PRIVATE METHODS ////////////////////////////////////////////////// #region Methods private static void HandleApiPropertyAttribute(IApiObjectTypeBuilder apiObjectTypeBuilder, ApiPrecedenceStack apiPrecedenceStack, PropertyInfo clrPropertyInfo) { Contract.Requires(apiObjectTypeBuilder != null); Contract.Requires(apiPrecedenceStack != null); Contract.Requires(clrPropertyInfo != null); var apiPropertyAttribute = (ApiPropertyAttribute)Attribute.GetCustomAttribute(clrPropertyInfo, typeof(ApiPropertyAttribute)); if (apiPropertyAttribute == null) { return; } var clrPropertyName = clrPropertyInfo.Name; var clrPropertyType = clrPropertyInfo.PropertyType; if (apiPropertyAttribute.Excluded) { apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiObjectTypeBuilder.Exclude(clrPropertyName); apiPrecedenceStack.Pop(); return; } IApiPropertyBuilder ApiPropertyConfiguration(IApiPropertyBuilder apiPropertyBuilder) { apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); if (String.IsNullOrWhiteSpace(apiPropertyAttribute.Name) == false) { apiPropertyBuilder.HasName(apiPropertyAttribute.Name); } if (String.IsNullOrWhiteSpace(apiPropertyAttribute.Description) == false) { apiPropertyBuilder.HasDescription(apiPropertyAttribute.Description); } if (apiPropertyAttribute.Required) { apiPropertyBuilder.IsRequired(); } // ReSharper disable once InvertIf if (apiPropertyAttribute.ItemRequired) { IApiCollectionTypeBuilder ApiCollectionTypeConfiguration(IApiCollectionTypeBuilder apiCollectionTypeBuilder) { apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiCollectionTypeBuilder.ItemIsRequired(); apiPrecedenceStack.Pop(); return(apiCollectionTypeBuilder); } apiPropertyBuilder.ApiCollectionType(ApiCollectionTypeConfiguration); } apiPrecedenceStack.Pop(); return(apiPropertyBuilder); } apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiObjectTypeBuilder.ApiProperty(clrPropertyName, clrPropertyType, ApiPropertyConfiguration); apiPrecedenceStack.Pop(); }