private MethodDeclarationSyntax CreateMembersForEndpoints( KeyValuePair <OperationType, OpenApiOperation> apiOperation, string urlPath, string area, bool hasRouteParameters) { var operationName = apiOperation.Value.GetOperationName(); var interfaceName = "I" + operationName + NameConstants.ContractHandler; var methodName = operationName + "Async"; var helperMethodName = $"Invoke{operationName}Async"; var parameterTypeName = operationName + NameConstants.ContractParameters; // Create method # use CreateParameterList & CreateCodeBlockReturnStatement var methodDeclaration = SyntaxFactory.MethodDeclaration( SyntaxFactory.GenericName(SyntaxFactory.Identifier(nameof(Task))) .WithTypeArgumentList(SyntaxTypeArgumentListFactory.CreateWithOneItem(nameof(ActionResult))), SyntaxFactory.Identifier(methodName)) .AddModifiers(SyntaxTokenFactory.PublicKeyword()) .WithParameterList(CreateParameterList(apiOperation.Value.HasParametersOrRequestBody() || hasRouteParameters, parameterTypeName, interfaceName, true)) .WithBody( SyntaxFactory.Block( SyntaxIfStatementFactory.CreateParameterArgumentNullCheck("handler", false), CreateCodeBlockReturnStatement(helperMethodName, apiOperation.Value.HasParametersOrRequestBody() || hasRouteParameters))); // Create and add Http-method-attribute var httpAttributeRoutePart = GetHttpAttributeRoutePart(urlPath); methodDeclaration = string.IsNullOrEmpty(httpAttributeRoutePart) ? methodDeclaration.AddAttributeLists( SyntaxAttributeListFactory.Create($"Http{apiOperation.Key}")) : methodDeclaration.AddAttributeLists( SyntaxAttributeListFactory.CreateWithOneItemWithOneArgument( $"Http{apiOperation.Key}", httpAttributeRoutePart)); // Create and add RequestFormLimits-attribute if (apiOperation.Value.HasRequestBodyWithAnythingAsFormatTypeBinary()) { methodDeclaration = methodDeclaration.AddAttributeLists( SyntaxAttributeListFactory.Create( "RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue)")); } // Create and add producesResponseTypes-attributes var producesResponseAttributeParts = apiOperation.Value.Responses.GetProducesResponseAttributeParts( OperationSchemaMappings, area, ApiProjectOptions.ProjectName, ApiProjectOptions.ApiOptions.Generator.Response.UseProblemDetailsAsDefaultBody, apiOperation.Value.HasParametersOrRequestBody(), includeIfNotDefinedAuthorization: false, includeIfNotDefinedInternalServerError: false); return(producesResponseAttributeParts .Aggregate( methodDeclaration, (current, producesResponseAttributePart) => current.AddAttributeLists( SyntaxAttributeListFactory.Create(producesResponseAttributePart)))); }
public bool GenerateCode() { var controllerTypeName = FocusOnSegmentName.EnsureFirstCharacterToUpper() + "Controller"; // Create compilationUnit var compilationUnit = SyntaxFactory.CompilationUnit(); // Create a namespace var @namespace = SyntaxProjectFactory.CreateNamespace( ApiProjectOptions, NameConstants.Endpoints); // Create class var classDeclaration = SyntaxClassDeclarationFactory.Create(controllerTypeName); if (ApiProjectOptions.ApiOptions.Generator.UseAuthorization) { classDeclaration = classDeclaration.AddAttributeLists( SyntaxAttributeListFactory.Create(nameof(AuthorizeAttribute))); } classDeclaration = classDeclaration.AddAttributeLists( SyntaxAttributeListFactory.Create(nameof(ApiControllerAttribute)), SyntaxAttributeListFactory.CreateWithOneItemWithOneArgument(nameof(RouteAttribute), $"api/{ApiProjectOptions.ApiVersion}/{FocusOnSegmentName}")) .AddBaseListTypes(SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName(nameof(ControllerBase)))) .AddGeneratedCodeAttribute(ApiProjectOptions.ToolName, ApiProjectOptions.ToolVersion.ToString()) .WithLeadingTrivia(SyntaxDocumentationFactory.CreateForEndpoints(FocusOnSegmentName)); // Create Methods var usedApiOperations = new List <OpenApiOperation>(); foreach (var(key, value) in ApiProjectOptions.Document.GetPathsByBasePathSegmentName(FocusOnSegmentName)) { var hasRouteParameters = value.HasParameters(); foreach (var apiOperation in value.Operations) { var methodDeclaration = CreateMembersForEndpoints(apiOperation, key, FocusOnSegmentName, hasRouteParameters) .WithLeadingTrivia(SyntaxDocumentationFactory.CreateForEndpointMethods(apiOperation, FocusOnSegmentName)); classDeclaration = classDeclaration.AddMembers(methodDeclaration); usedApiOperations.Add(apiOperation.Value); } } // Create private part for methods foreach (var(_, value) in ApiProjectOptions.Document.GetPathsByBasePathSegmentName(FocusOnSegmentName)) { var hasRouteParameters = value.HasParameters(); foreach (var apiOperation in value.Operations) { var methodDeclaration = CreateMembersForEndpointsPrivateHelper(apiOperation, hasRouteParameters); classDeclaration = classDeclaration.AddMembers(methodDeclaration); usedApiOperations.Add(apiOperation.Value); } } // Add the class to the namespace. @namespace = @namespace.AddMembers(classDeclaration); // Add using statement to compilationUnit var includeRestResults = classDeclaration .Select <IdentifierNameSyntax>() .Any(x => x.Identifier.ValueText.Contains($"({Microsoft.OpenApi.Models.NameConstants.Pagination}<", StringComparison.Ordinal)); compilationUnit = compilationUnit.AddUsingStatements( ProjectEndpointsFactory.CreateUsingList( ApiProjectOptions, FocusOnSegmentName, usedApiOperations, includeRestResults)); // Add namespace to compilationUnit compilationUnit = compilationUnit.AddMembers(@namespace); // Set code property Code = compilationUnit; return(true); }