diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs index 0920fb1ef..43088bf6b 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReferenceable.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. using Microsoft.OpenApi.Models; -using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Interfaces { diff --git a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs index f672b7dd1..0db85ed77 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiComponents.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiComponents.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index 268007141..8cc1fda6c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -587,6 +587,67 @@ public static ReadResult Parse(string input, { return OpenApiModelFactory.Parse(input, format, settings); } + /// + /// Adds a component to the components object of the current document and registers it to the underlying workspace. + /// + /// The component to add + /// The id for the component + /// The type of the component + /// Whether the component was added to the components. + /// Thrown when the component is null. + /// Thrown when the id is null or empty. + public bool AddComponent(string id, T componentToRegister) + { + Utils.CheckArgumentNull(componentToRegister); + Utils.CheckArgumentNullOrEmpty(id); + Components ??= new(); + switch (componentToRegister) + { + case OpenApiSchema openApiSchema: + Components.Schemas ??= new Dictionary(); + Components.Schemas.Add(id, openApiSchema); + break; + case OpenApiParameter openApiParameter: + Components.Parameters ??= new Dictionary(); + Components.Parameters.Add(id, openApiParameter); + break; + case OpenApiResponse openApiResponse: + Components.Responses ??= new Dictionary(); + Components.Responses.Add(id, openApiResponse); + break; + case OpenApiRequestBody openApiRequestBody: + Components.RequestBodies ??= new Dictionary(); + Components.RequestBodies.Add(id, openApiRequestBody); + break; + case OpenApiLink openApiLink: + Components.Links ??= new Dictionary(); + Components.Links.Add(id, openApiLink); + break; + case OpenApiCallback openApiCallback: + Components.Callbacks ??= new Dictionary(); + Components.Callbacks.Add(id, openApiCallback); + break; + case OpenApiPathItem openApiPathItem: + Components.PathItems ??= new Dictionary(); + Components.PathItems.Add(id, openApiPathItem); + break; + case OpenApiExample openApiExample: + Components.Examples ??= new Dictionary(); + Components.Examples.Add(id, openApiExample); + break; + case OpenApiHeader openApiHeader: + Components.Headers ??= new Dictionary(); + Components.Headers.Add(id, openApiHeader); + break; + case OpenApiSecurityScheme openApiSecurityScheme: + Components.SecuritySchemes ??= new Dictionary(); + Components.SecuritySchemes.Add(id, openApiSecurityScheme); + break; + default: + throw new ArgumentException($"Component type {componentToRegister!.GetType().Name} is not supported."); + } + return Workspace?.RegisterComponentForDocument(this, componentToRegister, id) ?? false; + } } internal class FindSchemaReferences : OpenApiVisitorBase diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs index 3e2c5b53c..41a1dceb5 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSchemaReference.cs @@ -14,21 +14,68 @@ namespace Microsoft.OpenApi.Models.References /// public class OpenApiSchemaReference : OpenApiSchema { - internal OpenApiSchema _target; + #nullable enable + private OpenApiSchema? _target; private readonly OpenApiReference _reference; - private string _description; - private JsonNode _default; - private JsonNode _example; - private IList _examples; + private string? _description; + private JsonNode? _default; + private JsonNode? _example; + private IList? _examples; + private bool? _nullable; + private IDictionary? _properties; + private string? _title; + private string? _schema; + private string? _comment; + private string? _id; + private string? _dynamicRef; + private string? _dynamicAnchor; + private IDictionary? _vocabulary; + private IDictionary? _definitions; + private decimal? _v31ExclusiveMaximum; + private decimal? _v31ExclusiveMinimum; + private bool? _unEvaluatedProperties; + private JsonSchemaType? _type; + private string? _const; + private string? _format; + private decimal? _maximum; + private bool? _exclusiveMaximum; + private decimal? _minimum; + private bool? _exclusiveMinimum; + private int? _maxLength; + private int? _minLength; + private string? _pattern; + private decimal? _multipleOf; + private bool? _readOnly; + private bool? _writeOnly; + private IList? _allOf; + private IList? _oneOf; + private IList? _anyOf; + private OpenApiSchema? _not; + private ISet? _required; + private OpenApiSchema _items; + private int? _maxItems; + private int? _minItems; + private bool? _uniqueItems; + private IDictionary? _patternProperties; + private int? _maxProperties; + private int? _minProperties; + private bool? _additionalPropertiesAllowed; + private OpenApiSchema? _additionalProperties; + private OpenApiDiscriminator? _discriminator; + private OpenApiExternalDocs? _externalDocs; + private bool? _deprecated; + private OpenApiXml? _xml; + private IDictionary? _extensions; + private bool? _unevaluatedProperties; + private IList? _enum; - private OpenApiSchema Target + private OpenApiSchema? Target + #nullable restore { get { _target ??= Reference.HostDocument?.ResolveReferenceTo(_reference); - OpenApiSchema resolved = new OpenApiSchema(_target); - if (!string.IsNullOrEmpty(_description)) resolved.Description = _description; - return resolved; + return _target; } } @@ -69,123 +116,111 @@ internal OpenApiSchemaReference(OpenApiSchema target, string referenceId) } /// - public override string Title { get => Target.Title; set => Target.Title = value; } + public override string Title { get => string.IsNullOrEmpty(_title) ? Target?.Title : _title; set => _title = value; } /// - public override string Schema { get => Target.Schema; set => Target.Schema = value; } + public override string Schema { get => string.IsNullOrEmpty(_schema) ? Target?.Schema : _schema; set => _schema = value; } /// - public override string Id { get => Target.Id; set => Target.Id = value; } + public override string Id { get => string.IsNullOrEmpty(_id) ? Target?.Id : _id; set => _id = value; } /// - public override string Comment { get => Target.Comment; set => Target.Comment = value; } + public override string Comment { get => string.IsNullOrEmpty(_comment) ? Target?.Comment : _comment; set => _comment = value; } /// - public override IDictionary Vocabulary { get => Target.Vocabulary; set => Target.Vocabulary = value; } + public override IDictionary Vocabulary { get => _vocabulary is not null ? _vocabulary : Target?.Vocabulary; set => _vocabulary = value; } /// - public override string DynamicRef { get => Target.DynamicRef; set => Target.DynamicRef = value; } + public override string DynamicRef { get => string.IsNullOrEmpty(_dynamicRef) ? Target?.DynamicRef : _dynamicRef; set => _dynamicRef = value; } /// - public override string DynamicAnchor { get => Target.DynamicAnchor; set => Target.DynamicAnchor = value; } + public override string DynamicAnchor { get => string.IsNullOrEmpty(_dynamicAnchor) ? Target?.DynamicAnchor : _dynamicAnchor; set => _dynamicAnchor = value; } /// - public override IDictionary Definitions { get => Target.Definitions; set => Target.Definitions = value; } + public override IDictionary Definitions { get => _definitions is not null ? _definitions : Target?.Definitions; set => _definitions = value; } /// - public override decimal? V31ExclusiveMaximum { get => Target.V31ExclusiveMaximum; set => Target.V31ExclusiveMaximum = value; } + public override decimal? V31ExclusiveMaximum { get => _v31ExclusiveMaximum is not null ? _v31ExclusiveMaximum.Value : Target?.V31ExclusiveMaximum; set => _v31ExclusiveMaximum = value; } /// - public override decimal? V31ExclusiveMinimum { get => Target.V31ExclusiveMinimum; set => Target.V31ExclusiveMinimum = value; } + public override decimal? V31ExclusiveMinimum { get => _v31ExclusiveMinimum is not null ? _v31ExclusiveMinimum.Value : Target?.V31ExclusiveMinimum; set => _v31ExclusiveMinimum = value; } /// - public override bool UnEvaluatedProperties { get => Target.UnEvaluatedProperties; set => Target.UnEvaluatedProperties = value; } + public override bool UnEvaluatedProperties { get => _unEvaluatedProperties is not null ? _unEvaluatedProperties.Value : Target?.UnEvaluatedProperties ?? false; set => _unEvaluatedProperties = value; } /// - public override JsonSchemaType? Type { get => Target.Type; set => Target.Type = value; } + public override JsonSchemaType? Type { get => _type is not null ? _type.Value : Target?.Type; set => _type = value; } /// - public override string Const { get => Target.Const; set => Target.Const = value; } + public override string Const { get => string.IsNullOrEmpty(_const) ? Target?.Const : _const; set => _const = value; } /// - public override string Format { get => Target.Format; set => Target.Format = value; } + public override string Format { get => string.IsNullOrEmpty(_format) ? Target?.Format : _format; set => _format = value; } /// public override string Description { - get => string.IsNullOrEmpty(_description) ? Target.Description : _description; + get => string.IsNullOrEmpty(_description) ? Target?.Description : _description; set => _description = value; } /// - public override decimal? Maximum { get => Target.Maximum; set => Target.Maximum = value; } + public override decimal? Maximum { get => _maximum is not null ? _maximum : Target?.Maximum; set => _maximum = value; } /// - public override bool? ExclusiveMaximum { get => Target.ExclusiveMaximum; set => Target.ExclusiveMaximum = value; } + public override bool? ExclusiveMaximum { get => _exclusiveMaximum is not null ? _exclusiveMaximum : Target?.ExclusiveMaximum; set => _exclusiveMaximum = value; } /// - public override decimal? Minimum { get => Target.Minimum; set => Target.Minimum = value; } + public override decimal? Minimum { get => _minimum is not null ? _minimum : Target?.Minimum; set => _minimum = value; } /// - public override bool? ExclusiveMinimum { get => Target.ExclusiveMinimum; set => Target.ExclusiveMinimum = value; } + public override bool? ExclusiveMinimum { get => _exclusiveMinimum is not null ? _exclusiveMinimum : Target?.ExclusiveMinimum; set => _exclusiveMinimum = value; } /// - public override int? MaxLength { get => Target.MaxLength; set => Target.MaxLength = value; } + public override int? MaxLength { get => _maxLength is not null ? _maxLength : Target?.MaxLength; set => _maxLength = value; } /// - public override int? MinLength { get => Target.MinLength; set => Target.MinLength = value; } + public override int? MinLength { get => _minLength is not null ? _minLength : Target?.MinLength; set => _minLength = value; } /// - public override string Pattern { get => Target.Pattern; set => Target.Pattern = value; } + public override string Pattern { get => string.IsNullOrEmpty(_pattern) ? Target?.Pattern : _pattern; set => _pattern = value; } /// - public override decimal? MultipleOf { get => Target.MultipleOf; set => Target.MultipleOf = value; } + public override decimal? MultipleOf { get => _multipleOf is not null ? _multipleOf : Target?.MultipleOf; set => _multipleOf = value; } /// - public override JsonNode Default - { - get => _default ??= Target.Default; - set => _default = value; - } + public override JsonNode Default { get => _default is not null ? _default : Target?.Default; set => _default = value; } /// - public override bool ReadOnly { get => Target.ReadOnly; set => Target.ReadOnly = value; } + public override bool ReadOnly { get => _readOnly is not null ? _readOnly.Value : Target?.ReadOnly ?? false; set => _readOnly = value; } /// - public override bool WriteOnly { get => Target.WriteOnly; set => Target.WriteOnly = value; } + public override bool WriteOnly { get => _writeOnly is not null ? _writeOnly.Value : Target?.WriteOnly ?? false; set => _writeOnly = value; } /// - public override IList AllOf { get => Target.AllOf; set => Target.AllOf = value; } + public override IList AllOf { get => _allOf is not null ? _allOf : Target?.AllOf; set => _allOf = value; } /// - public override IList OneOf { get => Target.OneOf; set => Target.OneOf = value; } + public override IList OneOf { get => _oneOf is not null ? _oneOf : Target?.OneOf; set => _oneOf = value; } /// - public override IList AnyOf { get => Target.AnyOf; set => Target.AnyOf = value; } + public override IList AnyOf { get => _anyOf is not null ? _anyOf : Target?.AnyOf; set => _anyOf = value; } /// - public override OpenApiSchema Not { get => Target.Not; set => Target.Not = value; } + public override OpenApiSchema Not { get => _not is not null ? _not : Target?.Not; set => _not = value; } /// - public override ISet Required { get => Target.Required; set => Target.Required = value; } + public override ISet Required { get => _required is not null ? _required : Target?.Required; set => _required = value; } /// - public override OpenApiSchema Items { get => Target.Items; set => Target.Items = value; } + public override OpenApiSchema Items { get => _items is not null ? _items : Target?.Items; set => _items = value; } /// - public override int? MaxItems { get => Target.MaxItems; set => Target.MaxItems = value; } + public override int? MaxItems { get => _maxItems is not null ? _maxItems : Target?.MaxItems; set => _maxItems = value; } /// - public override int? MinItems { get => Target.MinItems; set => Target.MinItems = value; } + public override int? MinItems { get => _minItems is not null ? _minItems : Target?.MinItems; set => _minItems = value; } /// - public override bool? UniqueItems { get => Target.UniqueItems; set => Target.UniqueItems = value; } + public override bool? UniqueItems { get => _uniqueItems is not null ? _uniqueItems : Target?.UniqueItems; set => _uniqueItems = value; } /// - public override IDictionary Properties { get => Target.Properties; set => Target.Properties = value; } + public override IDictionary Properties { get => _properties is not null ? _properties : Target?.Properties ; set => _properties = value; } /// - public override IDictionary PatternProperties { get => Target.PatternProperties; set => Target.PatternProperties = value; } + public override IDictionary PatternProperties { get => _patternProperties is not null ? _patternProperties : Target?.PatternProperties; set => _patternProperties = value; } /// - public override int? MaxProperties { get => Target.MaxProperties; set => Target.MaxProperties = value; } + public override int? MaxProperties { get => _maxProperties is not null ? _maxProperties : Target?.MaxProperties; set => _maxProperties = value; } /// - public override int? MinProperties { get => Target.MinProperties; set => Target.MinProperties = value; } + public override int? MinProperties { get => _minProperties is not null ? _minProperties : Target?.MinProperties; set => _minProperties = value; } /// - public override bool AdditionalPropertiesAllowed { get => Target.AdditionalPropertiesAllowed; set => Target.AdditionalPropertiesAllowed = value; } + public override bool AdditionalPropertiesAllowed { get => _additionalPropertiesAllowed is not null ? _additionalPropertiesAllowed.Value : Target?.AdditionalPropertiesAllowed ?? true; set => _additionalPropertiesAllowed = value; } /// - public override OpenApiSchema AdditionalProperties { get => Target.AdditionalProperties; set => Target.AdditionalProperties = value; } + public override OpenApiSchema AdditionalProperties { get => _additionalProperties is not null ? _additionalProperties : Target?.AdditionalProperties; set => _additionalProperties = value; } /// - public override OpenApiDiscriminator Discriminator { get => Target.Discriminator; set => Target.Discriminator = value; } + public override OpenApiDiscriminator Discriminator { get => _discriminator is not null ? _discriminator : Target?.Discriminator; set => _discriminator = value; } /// - public override JsonNode Example - { - get => _example ??= Target.Example; - set => _example = value; - } + public override JsonNode Example { get => _example is not null ? _example : Target?.Example; set => _example = value; } /// - public override IList Examples - { - get => _examples ??= Target.Examples; - set => Target.Examples = value; - } + public override IList Examples { get => _examples is not null ? _examples : Target?.Examples; set => _examples = value; } /// - public override IList Enum { get => Target.Enum; set => Target.Enum = value; } + public override IList Enum { get => _enum is not null ? _enum : Target?.Enum; set => _enum = value; } /// - public override bool Nullable { get => Target.Nullable; set => Target.Nullable = value; } + public override bool Nullable { get => _nullable is not null ? _nullable.Value : Target?.Nullable ?? false; set => _nullable = value; } /// - public override bool UnevaluatedProperties { get => Target.UnevaluatedProperties; set => Target.UnevaluatedProperties = value; } + public override bool UnevaluatedProperties { get => _unevaluatedProperties is not null ? _unevaluatedProperties.Value : Target?.UnevaluatedProperties ?? false; set => _unevaluatedProperties = value; } /// - public override OpenApiExternalDocs ExternalDocs { get => Target.ExternalDocs; set => Target.ExternalDocs = value; } + public override OpenApiExternalDocs ExternalDocs { get => _externalDocs is not null ? _externalDocs : Target?.ExternalDocs; set => _externalDocs = value; } /// - public override bool Deprecated { get => Target.Deprecated; set => Target.Deprecated = value; } + public override bool Deprecated { get => _deprecated is not null ? _deprecated.Value : Target?.Deprecated ?? false; set => _deprecated = value; } /// - public override OpenApiXml Xml { get => Target.Xml; set => Target.Xml = value; } + public override OpenApiXml Xml { get => _xml is not null ? _xml : Target?.Xml; set => _xml = value; } /// - public override IDictionary Extensions { get => Target.Extensions; set => Target.Extensions = value; } + public override IDictionary Extensions { get => _extensions is not null ? _extensions : Target?.Extensions; set => _extensions = value; } /// public override void SerializeAsV31(IOpenApiWriter writer) @@ -249,7 +284,6 @@ public override void SerializeAsV2(IOpenApiWriter writer) if (!writer.GetSettings().ShouldInlineReference(_reference)) { _reference.SerializeAsV2(writer); - return; } else { diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs index 664f784f3..64b815fd4 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs @@ -80,7 +80,6 @@ public override void SerializeAsV3(IOpenApiWriter writer) if (!writer.GetSettings().ShouldInlineReference(_reference)) { _reference.SerializeAsV3(writer); - return; } else { @@ -94,7 +93,6 @@ public override void SerializeAsV31(IOpenApiWriter writer) if (!writer.GetSettings().ShouldInlineReference(_reference)) { _reference.SerializeAsV31(writer); - return; } else { @@ -108,7 +106,6 @@ public override void SerializeAsV2(IOpenApiWriter writer) if (!writer.GetSettings().ShouldInlineReference(_reference)) { _reference.SerializeAsV2(writer); - return; } else { @@ -119,7 +116,7 @@ public override void SerializeAsV2(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); writer.WriteValue(Name); } } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs index b227b06e9..f92e6f322 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs @@ -54,6 +54,7 @@ public int ComponentsCount() { return _IOpenApiReferenceableRegistry.Count + _artifactsRegistry.Count; } + private const string ComponentSegmentSeparator = "/"; /// /// Registers a document's components into the workspace @@ -63,13 +64,13 @@ public void RegisterComponents(OpenApiDocument document) { if (document?.Components == null) return; - string baseUri = document.BaseUri + OpenApiConstants.ComponentsSegment; + string baseUri = getBaseUri(document); string location; // Register Schema foreach (var item in document.Components.Schemas) { - location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + "/" + item.Key; + location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } @@ -77,67 +78,108 @@ public void RegisterComponents(OpenApiDocument document) // Register Parameters foreach (var item in document.Components.Parameters) { - location = baseUri + ReferenceType.Parameter.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register Responses foreach (var item in document.Components.Responses) { - location = baseUri + ReferenceType.Response.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register RequestBodies foreach (var item in document.Components.RequestBodies) { - location = baseUri + ReferenceType.RequestBody.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register Links foreach (var item in document.Components.Links) { - location = baseUri + ReferenceType.Link.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register Callbacks foreach (var item in document.Components.Callbacks) { - location = baseUri + ReferenceType.Callback.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register PathItems foreach (var item in document.Components.PathItems) { - location = baseUri + ReferenceType.PathItem.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register Examples foreach (var item in document.Components.Examples) { - location = baseUri + ReferenceType.Example.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register Headers foreach (var item in document.Components.Headers) { - location = baseUri + ReferenceType.Header.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } // Register SecuritySchemes foreach (var item in document.Components.SecuritySchemes) { - location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + "/" + item.Key; + location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + item.Key; RegisterComponent(location, item.Value); } } + private string getBaseUri(OpenApiDocument openApiDocument) + { + return openApiDocument.BaseUri + OpenApiConstants.ComponentsSegment; + } + + /// + /// Registers a component for a document in the workspace + /// + /// The document to register the component for. + /// The component to register. + /// The id of the component. + /// The type of the component to register. + /// true if the component is successfully registered; otherwise false. + /// openApiDocument is null + /// componentToRegister is null + /// id is null or empty + public bool RegisterComponentForDocument(OpenApiDocument openApiDocument, T componentToRegister, string id) + { + Utils.CheckArgumentNull(openApiDocument); + Utils.CheckArgumentNull(componentToRegister); + Utils.CheckArgumentNullOrEmpty(id); + + var baseUri = getBaseUri(openApiDocument); + + var location = componentToRegister switch + { + OpenApiSchema => baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiParameter => baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiResponse => baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiRequestBody => baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiLink => baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiCallback => baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiPathItem => baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiExample => baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiHeader => baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + id, + OpenApiSecurityScheme => baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + id, + _ => throw new ArgumentException($"Invalid component type {componentToRegister.GetType().Name}"), + }; + + return RegisterComponent(location, componentToRegister); + } /// /// Registers a component in the component registry. @@ -145,7 +187,7 @@ public void RegisterComponents(OpenApiDocument document) /// /// /// true if the component is successfully registered; otherwise false. - public bool RegisterComponent(string location, T component) + internal bool RegisterComponent(string location, T component) { var uri = ToLocationUrl(location); if (component is IOpenApiReferenceable referenceable) diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 1b8857c0f..88599f6ef 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -569,6 +569,7 @@ namespace Microsoft.OpenApi.Models public System.Collections.Generic.IList? Tags { get; set; } public System.Collections.Generic.IDictionary? Webhooks { get; set; } public Microsoft.OpenApi.Services.OpenApiWorkspace? Workspace { get; set; } + public bool AddComponent(string id, T componentToRegister) { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1528,7 +1529,7 @@ namespace Microsoft.OpenApi.Services public int ComponentsCount() { } public bool Contains(string location) { } public System.Uri GetDocumentId(string key) { } - public bool RegisterComponent(string location, T component) { } + public bool RegisterComponentForDocument(Microsoft.OpenApi.Models.OpenApiDocument openApiDocument, T componentToRegister, string id) { } public void RegisterComponents(Microsoft.OpenApi.Models.OpenApiDocument document) { } public T? ResolveReference(string location) { } } diff --git a/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiReferencableTests.cs b/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiReferencableTests.cs index e015da4f4..ecadc2017 100644 --- a/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiReferencableTests.cs +++ b/test/Microsoft.OpenApi.Tests/Workspaces/OpenApiReferencableTests.cs @@ -45,7 +45,6 @@ public class OpenApiReferencableTests { "link1", new OpenApiLink() } } }; - private static readonly OpenApiSchema _schemaFragment = new OpenApiSchema(); private static readonly OpenApiSecurityScheme _securitySchemeFragment = new OpenApiSecurityScheme(); private static readonly OpenApiTag _tagFragment = new OpenApiTag();