// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiSchemaConvention Implementation public void Apply(IApiSchemaBuilder apiSchemaBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiSchemaBuilder != null); apiConventionSettings = apiConventionSettings ?? ApiConventionSettings.Empty; var apiDiscoverySettings = apiConventionSettings.ApiDiscoverySettings; var assemblies = apiDiscoverySettings.Assemblies; var clrTypes = assemblies.SelectMany(x => x.GetExportedTypes()) .ToList(); foreach (var clrType in clrTypes) { var apiTypeKind = clrType.GetApiTypeKind(); switch (apiTypeKind) { case ApiTypeKind.Object: { if (ClrTypeDiscoveryRules.CanAddApiObjectType(clrType) == false) { continue; } var apiTypeDiscoveryPredicateResult = apiDiscoverySettings.ApiTypeDiscoveryPredicate?.Invoke(clrType) ?? true; if (apiTypeDiscoveryPredicateResult == false) { continue; } apiSchemaBuilder.ApiObjectType(clrType); break; } } } }
// 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 IApiSchemaConvention Implementation public void Apply(IApiSchemaBuilder apiSchemaBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiSchemaBuilder != null); apiConventionSettings = apiConventionSettings ?? ApiConventionSettings.Empty; var apiDiscoverySettings = apiConventionSettings.ApiDiscoverySettings; var assemblies = apiDiscoverySettings.Assemblies; var clrTypes = assemblies.SelectMany(x => x.GetExportedTypes()) .ToList(); foreach (var clrType in clrTypes) { if (ClrTypeDiscoveryRules.CanAddApiTypeConfiguration(clrType) == false) { continue; } var apiConfigurationDiscoveryPredicateResult = apiDiscoverySettings.ApiConfigurationDiscoveryPredicate?.Invoke(clrType) ?? true; if (apiConfigurationDiscoveryPredicateResult == false) { continue; } var apiTypeConfigurationNewExpression = ExpressionBuilder.New <ApiTypeConfiguration>(clrType); var apiTypeConfigurationNewLambda = apiTypeConfigurationNewExpression.Compile(); var apiTypeConfiguration = apiTypeConfigurationNewLambda(); apiSchemaBuilder.HasConfiguration(apiTypeConfiguration); } }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiSchemaConvention Implementation public void Apply(IApiSchemaBuilder apiSchemaBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiSchemaBuilder != null); apiConventionSettings = apiConventionSettings ?? ApiConventionSettings.Empty; var apiDiscoverySettings = apiConventionSettings.ApiDiscoverySettings; var assemblies = apiDiscoverySettings.Assemblies; var clrTypes = assemblies.SelectMany(x => x.GetExportedTypes()) .ToList(); var apiSchemaConfiguration = (ApiSchemaConfiguration)apiSchemaBuilder; var apiPrecedenceStack = apiSchemaConfiguration.ApiPrecedenceStack; foreach (var clrType in clrTypes) { var apiTypeKind = clrType.GetApiTypeKind(); switch (apiTypeKind) { case ApiTypeKind.Enumeration: { this.HandleApiEnumerationTypeAttribute(apiSchemaConfiguration, apiConventionSettings, apiPrecedenceStack, clrType); break; } case ApiTypeKind.Object: { this.HandleApiObjectTypeAttribute(apiSchemaConfiguration, apiConventionSettings, apiPrecedenceStack, clrType); break; } } } }
private void HandleApiObjectTypeAttribute(IApiSchemaBuilder apiSchemaBuilder, ApiConventionSettings apiConventionSettings, ApiPrecedenceStack apiPrecedenceStack, Type clrType) { Contract.Requires(apiSchemaBuilder != null); Contract.Requires(apiConventionSettings != null); Contract.Requires(clrType != null); var apiObjectTypeAttribute = (ApiObjectTypeAttribute)Attribute.GetCustomAttribute(clrType, typeof(ApiObjectTypeAttribute)); if (apiObjectTypeAttribute == null) { return; } if (ClrTypeDiscoveryRules.CanAddApiObjectType(clrType) == false) { return; } var apiDiscoverySettings = apiConventionSettings.ApiDiscoverySettings; var apiAnnotationDiscoveryPredicateResult = apiDiscoverySettings.ApiAnnotationDiscoveryPredicate?.Invoke(clrType) ?? true; if (apiAnnotationDiscoveryPredicateResult == false) { return; } if (apiObjectTypeAttribute.Excluded) { apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiSchemaBuilder.Exclude(clrType); apiPrecedenceStack.Pop(); return; } IApiObjectTypeBuilder ApiObjectTypeConfiguration(IApiObjectTypeBuilder apiObjectTypeBuilder) { apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); if (String.IsNullOrWhiteSpace(apiObjectTypeAttribute.Name) == false) { apiObjectTypeBuilder.HasName(apiObjectTypeAttribute.Name); } if (String.IsNullOrWhiteSpace(apiObjectTypeAttribute.Description) == false) { apiObjectTypeBuilder.HasDescription(apiObjectTypeAttribute.Description); } apiPrecedenceStack.Pop(); return(apiObjectTypeBuilder); } apiPrecedenceStack.Push(ApiPrecedenceLevel.Annotation); apiSchemaBuilder.ApiObjectType(clrType, ApiObjectTypeConfiguration); apiPrecedenceStack.Pop(); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiNamingConvention Implementation public string Apply(string oldName, ApiConventionSettings apiConventionSettings) { if (String.IsNullOrWhiteSpace(oldName)) { return(oldName); } var newName = oldName.Singularize(inputIsKnownToBePlural: false); return(newName); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiNamingConvention Implementation public string Apply(string oldName, ApiConventionSettings apiConventionSettings) { if (String.IsNullOrWhiteSpace(oldName)) { return(oldName); } var newName = oldName.Camelize(); return(newName); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiNamingConvention Implementation public string Apply(string oldName, ApiConventionSettings apiConventionSettings) { if (String.IsNullOrWhiteSpace(oldName)) { return(oldName); } var newName = oldName.Transform(To.UpperCase); return(newName); }
// PUBLIC METHODS /////////////////////////////////////////////////// #region IApiObjectTypeConvention Implementation public void Apply(IApiEnumerationTypeBuilder apiEnumerationTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiEnumerationTypeBuilder != null); var clrEnumerationType = apiEnumerationTypeBuilder.ClrType; var clrEnumerationFieldInfoCollection = ClrEnumerationValueDiscoveryRules.GetClrEnumerationValues(clrEnumerationType); var apiEnumerationTypeConfiguration = (ApiEnumerationTypeConfiguration)apiEnumerationTypeBuilder; var apiPrecedenceStack = apiEnumerationTypeConfiguration.ApiPrecedenceStack; foreach (var clrEnumerationFieldInfo in clrEnumerationFieldInfoCollection) { HandleApiEnumerationValueAttribute(apiEnumerationTypeBuilder, apiPrecedenceStack, clrEnumerationFieldInfo); } }
// 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(IApiEnumerationTypeBuilder apiEnumerationTypeBuilder, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiEnumerationTypeBuilder != null); // Call ApiEnumerationValue method on all the discoverable CLR enum values for the given CLR enum type. var clrEnumerationType = apiEnumerationTypeBuilder.ClrType; var clrEnumerationFieldInfoCollection = ClrEnumerationValueDiscoveryRules.GetClrEnumerationValues(clrEnumerationType); foreach (var clrFieldInfo in clrEnumerationFieldInfoCollection) { var clrName = clrFieldInfo.Name; var clrOrdinal = (int)Enum.Parse(clrEnumerationType, clrName); apiEnumerationTypeBuilder.ApiEnumerationValue(clrName, clrOrdinal); } }
// 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); } }
// 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; } } } }
// PRIVATE METHODS ////////////////////////////////////////////////// #region Methods private void ApplyApiPropertyNameConventions(string clrName, IApiConventionSet apiConventionSet, ApiConventionSettings apiConventionSettings) { Contract.Requires(clrName.SafeHasContent()); Contract.Requires(apiConventionSet != null); var apiPropertyNameConventions = apiConventionSet?.ApiPropertyNameConventions; if (apiPropertyNameConventions == null) { return; } var apiPropertyNameConventionsCollection = apiPropertyNameConventions.SafeToReadOnlyCollection(); if (!apiPropertyNameConventionsCollection.Any()) { return; } var apiName = clrName; apiName = apiPropertyNameConventionsCollection.Aggregate(apiName, (current, apiNamingConvention) => apiNamingConvention.Apply(current, apiConventionSettings)); this.HasName(apiName); }
private void ApplyApiEnumerationTypeConventions(IApiConventionSet apiConventionSet, ApiConventionSettings apiConventionSettings) { Contract.Requires(apiConventionSet != null); var apiEnumerationTypeConventions = apiConventionSet?.ApiEnumerationTypeConventions; if (apiEnumerationTypeConventions == null) { return; } foreach (var apiEnumerationTypeConvention in apiEnumerationTypeConventions) { apiEnumerationTypeConvention.Apply(this, apiConventionSettings); } }
// PRIVATE METHODS ////////////////////////////////////////////////// #region Methods private void ApplyApiEnumerationTypeNameConventions(Type clrEnumerationType, IApiConventionSet apiConventionSet, ApiConventionSettings apiConventionSettings) { Contract.Requires(clrEnumerationType != null); Contract.Requires(apiConventionSet != null); var apiEnumerationTypeNameConventions = apiConventionSet?.ApiEnumerationTypeNameConventions; if (apiEnumerationTypeNameConventions == null) { return; } var apiEnumerationTypeNameConventionsCollection = apiEnumerationTypeNameConventions.SafeToReadOnlyCollection(); if (!apiEnumerationTypeNameConventionsCollection.Any()) { return; } var apiName = clrEnumerationType.Name; apiName = apiEnumerationTypeNameConventionsCollection.Aggregate(apiName, (current, apiNamingConvention) => apiNamingConvention.Apply(current, apiConventionSettings)); var apiEnumerationTypeBuilder = (IApiEnumerationTypeBuilder)this; apiEnumerationTypeBuilder.HasName(apiName); }