예제 #1
0
        public override TVersionable Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType != JsonTokenType.StartObject)
            {
                throw new JsonException();
            }

            var output = Activator.CreateInstance <TVersionable>();

            var objectVersionHistory = typeof(TVersionable).GetVersionHistory();

            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndObject)
                {
                    return(output);
                }

                if (reader.TokenType != JsonTokenType.PropertyName)
                {
                    throw new JsonException();
                }

                var propertyName = reader.GetString();
                var propertyInfo = typeof(TVersionable).GetPropertyBySerialisationName(propertyName);

                if (propertyInfo != null)
                {
                    var propertyVersionHistory   = propertyInfo.GetVersionHistory();
                    var applicableVersionHistory = VersionHistory.Merge(propertyVersionHistory, objectVersionHistory);

                    if (applicableVersionHistory.IsApplicableAtVersion(_version))
                    {
                        var value = JsonSerializer.Deserialize(ref reader, propertyInfo.PropertyType, options);
                        propertyInfo.SetValue(output, value);
                    }
                }
            }

            throw new JsonException();
        }
예제 #2
0
        public override void Write(Utf8JsonWriter writer, TVersionable value, JsonSerializerOptions options)
        {
            writer.WriteStartObject();

            var objectVersionHistory = typeof(TVersionable).GetVersionHistory();

            foreach (var propertyInfo in typeof(TVersionable).GetProperties())
            {
                var propertyVersionHistory   = propertyInfo.GetVersionHistory();
                var applicableVersionHistory = VersionHistory.Merge(propertyVersionHistory, objectVersionHistory);

                if (applicableVersionHistory.IsApplicableAtVersion(_version))
                {
                    writer.WritePropertyName(propertyInfo.GetSerialisationName());

                    JsonSerializer.Serialize(writer, propertyInfo.GetValue(value), options);
                }
            }

            writer.WriteEndObject();
        }
        private static IDictionary <string, OpenApiSchema> GetPrunedSchemas(IDictionary <string, OpenApiSchema> schemas, Version version)
        {
            var prunedSchemas = new Dictionary <string, OpenApiSchema>();

            foreach (var schema in schemas.Where(s => s.Value?.Description != null))
            {
                var objectData = schema.Value.Description;

                // VersionableSwaggerSchemaAttribute packs data as "@[ClassName]@Description
                var regEx   = new Regex(@"^@\[(?'className'[\s\S]+)\]@(?'description'[\s\S]*)$");
                var matches = regEx.Matches(objectData);

                if (matches.Count == 0)
                {
                    // Not decorated with VersionableSwaggerSchemaAttribute so pass through untouched
                    prunedSchemas.Add(schema.Key, schema.Value);
                    continue;
                }

                var objectName = matches[0].Groups["className"].Value;
                schema.Value.Description = matches[0].Groups["description"].Value;

                if (string.IsNullOrWhiteSpace(objectName))
                {
                    // Can't determine Versionable object so pass through untouched
                    prunedSchemas.Add(schema.Key, schema.Value);
                    continue;
                }

                var objectType = Type.GetType(objectName);

                if (objectType == null || !objectType.IsClass)
                {
                    // Not Versionable so pass through untouched
                    prunedSchemas.Add(schema.Key, schema.Value);
                    continue;
                }

                var objectVersionHistory = objectType.GetVersionHistory();

                if (!objectVersionHistory.IsApplicableAtVersion(version))
                {
                    // Entire object not applicable - discard
                    continue;
                }

                var excludedProperties = new List <string>();

                foreach (var property in schema.Value.Properties)
                {
                    var propertyInfo = objectType.GetPropertyBySerialisationName(property.Key);

                    if (propertyInfo == null)
                    {
                        continue;
                    }

                    var propertyVersionHistory   = propertyInfo.GetVersionHistory();
                    var applicableVersionHistory = VersionHistory.Merge(propertyVersionHistory, objectVersionHistory);

                    if (!applicableVersionHistory.IsApplicableAtVersion(version))
                    {
                        excludedProperties.Add(property.Key);
                    }
                }

                foreach (var excludedProperty in excludedProperties.Where(excludedProperty => schema.Value.Properties.ContainsKey(excludedProperty)))
                {
                    schema.Value.Properties.Remove(excludedProperty);
                }

                prunedSchemas.Add(schema.Key, schema.Value);
            }

            return(prunedSchemas);
        }