diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index d680495c8..8cc1fda6c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -588,19 +588,65 @@ public static ReadResult Parse(string input, return OpenApiModelFactory.Parse(input, format, settings); } /// - /// Adds a schema to the components object of the current document. + /// Adds a component to the components object of the current document and registers it to the underlying workspace. /// - /// The schema to add + /// The component to add /// The id for the component - /// Whether the schema was added to the components. - public bool AddComponentSchema(string id, OpenApiSchema openApiSchema) + /// 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(openApiSchema); + Utils.CheckArgumentNull(componentToRegister); Utils.CheckArgumentNullOrEmpty(id); Components ??= new(); - Components.Schemas ??= new Dictionary(); - Components.Schemas.Add(id, openApiSchema); - return Workspace?.RegisterSchemaForDocument(this, openApiSchema, id) ?? false; + 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; } } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs index 1d8aa2799..f92e6f322 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs @@ -145,26 +145,40 @@ private string getBaseUri(OpenApiDocument openApiDocument) } /// - /// Registers a schema for a document in the workspace + /// Registers a component for a document in the workspace /// - /// The document to register the schema for. - /// The schema to register. - /// The id of the schema. - /// true if the schema is successfully registered; otherwise false. + /// 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 - /// openApiSchema is null + /// componentToRegister is null /// id is null or empty - public bool RegisterSchemaForDocument(OpenApiDocument openApiDocument, OpenApiSchema openApiSchema, string id) + public bool RegisterComponentForDocument(OpenApiDocument openApiDocument, T componentToRegister, string id) { Utils.CheckArgumentNull(openApiDocument); - Utils.CheckArgumentNull(openApiSchema); + Utils.CheckArgumentNull(componentToRegister); Utils.CheckArgumentNullOrEmpty(id); var baseUri = getBaseUri(openApiDocument); - var location = baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + id; - - return RegisterComponent(location, openApiSchema); + 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); } /// @@ -173,7 +187,7 @@ public bool RegisterSchemaForDocument(OpenApiDocument openApiDocument, OpenApiSc /// /// /// 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)