diff --git a/Source/DotNET/Applications/Queries/QueryMethodExtensions.cs b/Source/DotNET/Applications/Queries/QueryMethodExtensions.cs new file mode 100644 index 00000000..932acad5 --- /dev/null +++ b/Source/DotNET/Applications/Queries/QueryMethodExtensions.cs @@ -0,0 +1,27 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; +using Cratis.Reflection; +using Microsoft.AspNetCore.Mvc; + +namespace Cratis.Applications.Queries; + +/// +/// Extension methods for methods representing commands. +/// +public static class QueryMethodExtensions +{ + /// + /// Check if a method is a command. + /// + /// The to check. + /// True if it is a command, false if not. + public static bool IsQuery(this MethodInfo methodInfo) => + methodInfo.HasAttribute() && + methodInfo.ReturnType != typeof(void) && + methodInfo.ReturnType != typeof(Task) && + methodInfo.ReturnType != typeof(ValueTask) && + !methodInfo.HasAttribute() && + (!methodInfo.DeclaringType?.HasAttribute() ?? false); +} \ No newline at end of file diff --git a/Source/DotNET/Swagger/Extensions.cs b/Source/DotNET/Swagger/Extensions.cs index 410896f1..4242da2d 100644 --- a/Source/DotNET/Swagger/Extensions.cs +++ b/Source/DotNET/Swagger/Extensions.cs @@ -19,5 +19,6 @@ public static void AddConcepts(this SwaggerGenOptions options) { options.SchemaFilter(); options.OperationFilter(); + options.OperationFilter(); } } diff --git a/Source/DotNET/Swagger/QueryResultOperationFilter.cs b/Source/DotNET/Swagger/QueryResultOperationFilter.cs new file mode 100644 index 00000000..f35dc0d4 --- /dev/null +++ b/Source/DotNET/Swagger/QueryResultOperationFilter.cs @@ -0,0 +1,43 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Applications.Queries; +using Cratis.Concepts; +using Cratis.Reflection; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace Cratis.Applications.Swagger; + +/// +/// Represents an implementation of that adds the command result to the operation for command methods. +/// +/// The to use. +public class QueryResultOperationFilter(ISchemaGenerator schemaGenerator) : IOperationFilter +{ + /// + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + if (!context.MethodInfo.IsQuery()) return; + + var returnType = context.MethodInfo.GetActualReturnType(); + + if (returnType.IsConcept()) + { + returnType = returnType.GetConceptValueType(); + } + + var queryResultType = typeof(QueryResult<>).MakeGenericType(returnType); + + var schema = schemaGenerator.GenerateSchema(queryResultType, context.SchemaRepository); + var response = operation.Responses.First().Value; + if (response.Content.ContainsKey("application/json")) + { + operation.Responses.First().Value.Content["application/json"].Schema = schema; + } + else + { + response.Content.Add(new("application/json", new() { Schema = schema })); + } + } +}