コード例 #1
0
        /// <summary>
        /// Implements a common delivery framework method implementation for a missing member.
        /// </summary>
        /// <param name="memberData">Event data to be loaded.</param>
        /// <param name="manager">The namespace manager to use for namespace management with type declarations.</param>
        /// <param name="includeLogging">Flag that determines if enter, exit, and error logging should be included in a method implementation.</param>
        /// <param name="includeBoundsCheck">Flag that determines if string and nullable type bounds checking should be included in a method implementation.</param>
        /// <param name="supportAsyncKeyword">Flag that determines if methods should be implemented with the async keyword when supported by the method implementation.</param>
        /// <param name="isControllerAction">Flag that determines if the the method is a controller action. This will alter the error management logic.</param>
        /// <returns>The fully formatted method source code or null if the member could not be implemented.</returns>
        public static string FormatMemberMethod(CsMethod memberData, NamespaceManager manager, bool includeLogging,
                                                bool includeBoundsCheck, bool supportAsyncKeyword, bool isControllerAction)
        {
            //Bounds checking to make sure all data that is needed is provided. If any required data is missing will return null.
            if (memberData == null)
            {
                return(null);
            }
            if (!memberData.IsLoaded)
            {
                return(null);
            }
            if (manager == null)
            {
                return(null);
            }

            //C# helper used to format output syntax.
            var formatter = new CodeFactory.SourceFormatter();

            //Using the formatter helper to generate a method signature.
            string methodSyntax = supportAsyncKeyword
                ? memberData.CSharpFormatStandardMethodSignatureWithAsync(manager)
                : memberData.CSharpFormatStandardMethodSignature(manager);

            //If the method syntax was not created return.
            if (string.IsNullOrEmpty(methodSyntax))
            {
                return(null);
            }

            //If the member has document then will build the documentation.
            if (memberData.HasDocumentation)
            {
                //Using a documentation helper that will generate an enumerator that will output all XML documentation for the member.
                foreach (var documentation in memberData.CSharpFormatXmlDocumentationEnumerator())
                {
                    //Appending each xml document line to the being of the member definition.
                    formatter.AppendCodeLine(0, documentation);
                }
            }

            //The member has attributes assigned to it, append the attributes.
            if (memberData.HasAttributes)
            {
                //Using a documentation helper that will generate an enumerator that will output each attribute definition.
                foreach (var attributeSyntax in memberData.Attributes.CSharpFormatAttributeDeclarationEnumerator(manager))
                {
                    //Appending each attribute definition before the member definition.
                    formatter.AppendCodeLine(0, attributeSyntax);
                }
            }

            //Adding the method declaration
            formatter.AppendCodeLine(0, methodSyntax);
            formatter.AppendCodeLine(0, "{");

            //Adding enter logging if logging is enabled.
            if (includeLogging)
            {
                formatter.AppendCodeLine(1, "_logger.InformationEnterLog();");
                formatter.AppendCodeLine(0);
            }

            //Processing each parameter for bounds checking if bounds checking is enabled.
            if (includeBoundsCheck & memberData.HasParameters)
            {
                foreach (ICsParameter paramData in memberData.Parameters)
                {
                    //If the parameter has a default value then continue will not bounds check parameters with a default value.
                    if (paramData.HasDefaultValue)
                    {
                        continue;
                    }

                    //If the parameter is a string type add the following bounds check
                    if (paramData.ParameterType.WellKnownType == CsKnownLanguageType.String)
                    {
                        //Adding an if check
                        formatter.AppendCodeLine(1, $"if(string.IsNullOrEmpty({paramData.Name}))");
                        formatter.AppendCodeLine(1, "{");

                        //If logging was included add error logging and exit logging
                        if (includeLogging)
                        {
                            formatter.AppendCodeLine(2,
                                                     $"_logger.ErrorLog($\"The parameter {{nameof({paramData.Name})}} was not provided. Will raise an argument exception\");");
                            formatter.AppendCodeLine(2, "_logger.InformationExitLog();");
                        }

                        //Adding a throw of an argument null exception
                        formatter.AppendCodeLine(2, $"throw new ValidationException(nameof({paramData.Name}));");
                        formatter.AppendCodeLine(1, "}");
                        formatter.AppendCodeLine(0);
                    }

                    // Check to is if the parameter is not a value type or a well know type if not then go ahead and perform a null bounds check.
                    if (!paramData.ParameterType.IsValueType & !paramData.ParameterType.IsWellKnownType)
                    {
                        //Adding an if check
                        formatter.AppendCodeLine(1, $"if({paramData.Name} == null)");
                        formatter.AppendCodeLine(1, "{");

                        //If logging was included add error logging and exit logging
                        if (includeLogging)
                        {
                            formatter.AppendCodeLine(2,
                                                     $"_logger.ErrorLog($\"The parameter {{nameof({paramData.Name})}} was not provided. Will raise an argument exception\");");
                            formatter.AppendCodeLine(2, "_logger.InformationExitLog();");
                        }

                        //Adding a throw of an argument null exception
                        formatter.AppendCodeLine(2, $"throw new ValidationException(nameof({paramData.Name}));");
                        formatter.AppendCodeLine(1, "}");
                        formatter.AppendCodeLine(0);
                    }
                }
            }

            //Formatting standard try block for method
            formatter.AppendCodeLine(1, "try");
            formatter.AppendCodeLine(1, "{");
            formatter.AppendCodeLine(2, "//TODO: add execution logic here");
            formatter.AppendCodeLine(1, "}");

            //Formatting managed exception block for method
            if (!isControllerAction)
            {
                formatter.AppendCodeLine(1, "catch (ManagedException)");
                formatter.AppendCodeLine(1, "{");
                formatter.AppendCodeLine(2, "//Throwing the managed exception. Override this logic if you have logic in this method to handle managed errors.");
                formatter.AppendCodeLine(2, "throw;");
                formatter.AppendCodeLine(1, "}");
            }
            else
            {
                formatter.AppendCodeLine(1, "catch (ManagedException managedException)");
                formatter.AppendCodeLine(1, "{");
                formatter.AppendCodeLine(2, "//Throwing the managed exception. Override this logic if you have logic in this method to handle managed errors.");
                formatter.AppendCodeLine(2, "_logger.InformationExitLog();");
                formatter.AppendCodeLine(2, "return this.CreateProblemResult(managedException);");
                formatter.AppendCodeLine(1, "}");
            }

            //Formatting standard catch block for method
            formatter.AppendCodeLine(1, "catch (Exception unhandledException)");
            formatter.AppendCodeLine(1, "{");

            if (!isControllerAction)
            {
                formatter.AppendCodeLine(2,
                                         "_logger.ErrorLog(\"An unhandled exception occured, see the exception for details. Will throw a UnhandledException\", unhandledException);");
                formatter.AppendCodeLine(2, "_logger.InformationExitLog();");
                formatter.AppendCodeLine(2, "throw new UnhandledException();");
            }
            else
            {
                formatter.AppendCodeLine(2, " _logger.ErrorLog(\"An unhandled exception occured, see the exception for details. Will throw a UnhandledLogicException\", unhandledException);");
                formatter.AppendCodeLine(2, "_logger.InformationExitLog();");
                formatter.AppendCodeLine(2, "var unhandledError = new UnhandledException();");
                formatter.AppendCodeLine(2, "return this.CreateProblemResult(unhandledError);");
            }

            formatter.AppendCodeLine(1, "}");
            formatter.AppendCodeLine(0);

            //If logging add a logging exit statement.
            formatter.AppendCodeLine(1, "_logger.InformationExitLog();");

            //Add an exception for not implemented until the developer updates the logic.
            formatter.AppendCodeLine(1, "throw new NotImplementedException();");

            //if the return type is not void then add a to do message for the developer to add return logic.
            if (!memberData.IsVoid)
            {
                formatter.AppendCodeLine(0);
                formatter.AppendCodeLine(1, "//TODO: add return logic here");
            }
            formatter.AppendCodeLine(0, "}");
            formatter.AppendCodeLine(0);

            //Returning the fully formatted method.
            return(formatter.ReturnSource());
        }