示例#1
0
    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);
        }