Exemplo n.º 1
0
        /// <summary>
        /// Checks if the contract is valid, and throws if it is not.
        /// </summary>
        /// <param name="contract">The contract to check.</param>
        protected virtual void ValidateContract(ContractDefinition contract)
        {
            // Null check
            if (contract == null)
            {
                throw new ArgumentNullException(nameof(contract));
            }

            // Make sure we have a valid name, as the generated class will have this name
            if (!CSharpNamingUtils.IsValidIdentifier(contract.Name))
            {
                throw new ArgumentException($"Contract name is not a valid C# identifier: {contract.Name}", nameof(contract));
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generates the transmitter class.
        /// </summary>
        /// <param name="contract">The contract for which to generate the transmitter class.</param>
        /// <param name="implementationName">The name of the ouput class.  This will also be the name of the output file before appending the extension.</param>
        /// <param name="namespace">The namespace in which to put the generated classes.</param>
        /// <param name="accessLevel">The access level of the generated classes.</param>
        public string Run(
            ContractDefinition contract,
            string implementationName,
            string @namespace,
            CSharpAccessModifier accessLevel = CSharpAccessModifier.Public)
        {
            if (contract == null)
            {
                throw new ArgumentNullException(nameof(contract));
            }
            if (implementationName == null)
            {
                throw new ArgumentNullException(nameof(implementationName));
            }
            if (!CSharpNamingUtils.IsValidIdentifier(implementationName))
            {
                throw new ArgumentException($"Implementation name must be a valid class name: {implementationName}", nameof(implementationName));
            }
            if (@namespace == null)
            {
                throw new ArgumentNullException(nameof(@namespace));
            }

            foreach (string namespacePart in @namespace.Split('.'))
            {
                if (!CSharpNamingUtils.IsValidIdentifier(namespacePart))
                {
                    throw new ArgumentException($"The provided namespace is invalid because the part '{namespacePart}' is not a valid C# identifier: {@namespace}", nameof(@namespace));
                }
            }

            // Validate the contract
            this.ValidateContract(contract);

            // Generate the code
            CSharpFile file = this.GenerateCode(contract, implementationName, @namespace, accessLevel);

            string result = file.ToString();

            return(result);
        }
        private string GetMethodBody(OperationDefinition operation, bool isAsync, Type returnType)
        {
            string parametersVarName = "_parameters";
            string operationVarName  = "_operation";
            string resultVarName     = "_result";

            StringBuilder sb = new StringBuilder();

            // Get the parameters to the operation invocation
            string parameterValueTypeName = typeof(ParameterValue).GetCSharpName();

            sb.AppendLine("// Create the parameters list if needed");
            sb.Append($"{parameterValueTypeName}[] {parametersVarName} = ");
            if (!operation.Parameters.Any())
            {
                sb.AppendLine("null;");
            }
            else
            {
                // Create a new array of parameter values
                sb.AppendLine($"new {parameterValueTypeName}[] {{");

                // Add each parameter value
                foreach (ParameterDefinition parameter in operation.Parameters)
                {
                    string parameterName = CSharpNamingUtils.SanitizeIdentifier(parameter.Name);
                    sb.AppendLine($"new {parameterValueTypeName}(nameof({parameterName}), {parameter.Name}, \"{parameter.Type.FullName}\"),".Indent());
                }

                // Close the array
                sb.AppendLine("};");
            }
            sb.AppendLine();

            // Create the operation invocation object
            bool   returnsValue            = returnType != typeof(void);
            string operationTypeNameString = typeof(OperationInvocation).GetCSharpName();

            sb.AppendLine("// Create an object to represent the operation invocation");
            sb.AppendLine($"{operationTypeNameString} {operationVarName} = new {operationTypeNameString}(nameof({operation.Name}), {parametersVarName}, {(returnsValue ? "true" : "false")});");
            sb.AppendLine();

            // Call the appropriate transmit function, depending on whether or not it is 1) async or 2) needs to return a value
            sb.AppendLine("// Transmit the operation invocation so a receiver can forward it to an implementation which can execute it");
            if (returnsValue)
            { // Has a return value
                string returnTypeNameString = returnType.GetCSharpName();
                if (isAsync)
                {
                    sb.AppendLine($"{returnTypeNameString} {resultVarName} = await this.{nameof(Transmitter.RequestTransmitter)}.{nameof(IOperationInvocationTransmitter.TransmitRequestAsync)}<{returnTypeNameString}>({operationVarName});");
                }
                else
                {
                    sb.AppendLine($"{returnTypeNameString} {resultVarName} = this.{nameof(Transmitter.RequestTransmitter)}.{nameof(IOperationInvocationTransmitter.TransmitRequest)}<{returnTypeNameString}>({operationVarName});");
                }

                sb.AppendLine();
                sb.Append($"return {resultVarName};");
            }
            else
            { // Has no return value
                if (isAsync)
                {
                    sb.AppendLine($"await this.{nameof(Transmitter.RequestTransmitter)}.{nameof(IOperationInvocationTransmitter.TransmitMessageAsync)}({operationVarName});");
                }
                else
                {
                    sb.AppendLine($"this.{nameof(Transmitter.RequestTransmitter)}.{nameof(IOperationInvocationTransmitter.TransmitMessage)}({operationVarName});");
                }

                sb.AppendLine();
                sb.Append("return;");
            }

            string result = sb.ToString();

            return(result);
        }