/// <summary> /// Only constructor. /// </summary> /// <param name="ChanKind"></param> /// <param name="ObjType"></param> /// <param name="CallConv"></param> /// <param name="InvKind"></param> public Client(ChannelKind ChanKind, Type ObjType, CallingConvention CallConv, InvokeKind InvKind, string Host) { m_ChanKind = ChanKind; m_ObjType = ObjType; m_CallConv = CallConv; m_InvKind = InvKind; m_Host = Host; }//constructor
/// <summary> /// A basic helper for IDispatch::Invoke /// </summary> /// <param name="obj">The IDispatch object of which you want to invoke a member on</param> /// <param name="memberId">The dispatch ID of the member to invoke</param> /// <param name="invokeKind">See InvokeKind enumeration</param> /// <param name="args">Array of arguments to pass to the call, or null for no args</param> /// <remarks>TODO support DISPATCH_PROPERTYPUTREF (property-set) which requires special handling</remarks> /// <returns>An object representing the return value from the called routine</returns> public static object Invoke(IDispatch obj, int memberId, InvokeKind invokeKind, object[] args = null) { var pDispParams = PrepareDispatchArgs(args); var pExcepInfo = new ComTypes.EXCEPINFO(); var hr = obj.Invoke(memberId, ref _guid_null, 0, (uint)invokeKind, ref pDispParams, out var pVarResult, ref pExcepInfo, out var pErrArg); UnprepareDispatchArgs(pDispParams); if (ComHelper.HRESULT_FAILED(hr)) { if ((hr == (int)KnownComHResults.DISP_E_EXCEPTION) && (ComHelper.HRESULT_FAILED(pExcepInfo.scode))) { throw RdMarshal.GetExceptionForHR(pExcepInfo.scode); } throw RdMarshal.GetExceptionForHR(hr); } return(pVarResult); }
private void GenerateInvokeMethodReturn(DomainOperationEntry domainOperationEntry, string parameterDictionaryString, InvokeKind invokeKind) { InvokeAttribute invokeAttribute = (InvokeAttribute)domainOperationEntry.OperationAttribute; string returnTypeNameString = CodeGenUtilities.GetTypeName(CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType)); if(invokeKind == InvokeKind.Async) { returnTypeNameString = (domainOperationEntry.ReturnType == typeof(void)) ? string.Empty : string.Format("<{0}>", returnTypeNameString); this.Write("return this.InvokeOperationAsync"); this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); this.Write("(\""); this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); this.Write("\", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); this.Write(", \r\n"); this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); this.Write(");\r\n"); } else { this.Write("return this."); this.Write(this.ToStringHelper.ToStringWithCulture(this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind))); this.Write("(\""); this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); this.Write("\", typeof("); this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); this.Write("), "); this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); this.Write(", \r\n"); this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); this.Write(",\r\n"); if(invokeKind == InvokeKind.WithCallback) { this.Write("callback, userState);\r\n"); } else { this.Write("null, null);\r\n"); } } }
private void GenerateInvokeMethodBody(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { string parameterDictionaryString = this.GenerateServiceOpMethodBody(domainOperationEntry, domainOperationEntry.Name); this.GenerateInvokeMethodReturn(domainOperationEntry, parameterDictionaryString, invokeKind); }
private void GenerateInvokeOperationDeclaration(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { // First generate custom attributes for the qery method IEnumerable<Attribute> methodAttributes = domainOperationEntry.Attributes.Cast<Attribute>(); this.GenerateAttributes(methodAttributes); string invokeOperationReturnTypeName = this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind); var name = domainOperationEntry.Name; if(invokeKind == InvokeKind.Async) name = name + "Async"; this.Write("public "); this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(name)); this.Write("(\r\n"); this.GenerateParameterDeclaration(domainOperationEntry.Parameters, true); if(invokeKind == InvokeKind.WithCallback) { if(domainOperationEntry.Parameters.Count() > 0) { this.Write(", "); } this.Write("Action<"); this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); this.Write("> callback, object userState\r\n"); } this.Write(")\r\n"); }
/// <summary> /// Generates an async invoke operation. /// </summary> /// <param name="domainOperationEntry">The invoke operation to be generated.</param> /// <param name="invokeKind">The type of invoke operation to be generated.</param> protected virtual void GenerateInvokeOperation(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { this.GenerateInvokeOperationDeclaration(domainOperationEntry, invokeKind); this.GenerateOpeningBrace(); this.GenerateInvokeMethodBody(domainOperationEntry, invokeKind); this.GenerateClosingBrace(); }
internal string GetInvokeMethodReturnTypeName(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { Type returnType = CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType); string returnTypeString = (invokeKind == InvokeKind.Async) ? "InvokeResult" : "InvokeOperation"; if (returnType != typeof(void)) { if (!this.RegisterEnumTypeIfNecessary(returnType, domainOperationEntry)) { return(String.Empty); } returnTypeString = returnTypeString + "<" + CodeGenUtilities.GetTypeName(returnType) + ">"; } if (invokeKind == InvokeKind.Async) { returnTypeString = string.Format("System.Threading.Tasks.Task<{0}>", returnTypeString); } return(returnTypeString); }
/// <summary> /// Generates an invoke operation. /// </summary> /// <param name="domainOperationEntry">The invoke operation.</param> /// <param name="invokeKind">the type of invoke method to generate.</param> private void GenerateInvokeOperation(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { // Determine the name of the generated invoke function string methodName = domainOperationEntry.Name; // ---------------------------------------------------------------- // Check for name conflicts // ---------------------------------------------------------------- if ((invokeKind == InvokeKind.WithCallback) && this._proxyClass.Members.Cast <CodeTypeMember>().Any(c => c.Name == methodName && c.GetType() != typeof(CodeMemberMethod))) { this.ClientProxyGenerator.LogError( string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_NamingCollision_MemberAlreadyExists, this._proxyClass.Name, methodName)); return; } // ---------------------------------------------------------------- // InvokeResult<T> InvokeOperation(args); // // InvokeResult<T> InvokeOperation(args, callback, userState); // // Task<T> InvokeOperationAsync(args); // ---------------------------------------------------------------- CodeTypeReference operationReturnType = null; Type returnType = CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType); var methodReturnTypeName = (invokeKind == InvokeKind.Async) ? TypeConstants.InvokeResultTypeFullName: TypeConstants.InvokeOperationTypeFullName; CodeTypeReference invokeOperationType = CodeGenUtilities.GetTypeReference(methodReturnTypeName, (string)this._proxyClass.UserData["Namespace"], false); if (returnType != typeof(void)) { // If this is an enum type, we need to ensure it is either shared or // can be generated. Failure to use this enum is only a warning and causes // this invoke operation to be skipped. The test for legality also causes // the enum to be generated if required. Type enumType = TypeUtility.GetNonNullableType(returnType); if (enumType.IsEnum) { string errorMessage = null; if (!this.ClientProxyGenerator.CanExposeEnumType(enumType, out errorMessage)) { this.ClientProxyGenerator.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Domain_Op_Enum_Error, methodName, this._proxyClass.Name, enumType.FullName, errorMessage)); return; } else { // Register use of this enum type, which could cause deferred generation this.ClientProxyGenerator.RegisterUseOfEnumType(enumType); } } operationReturnType = CodeGenUtilities.GetTypeReference(returnType, this.ClientProxyGenerator, this._proxyClass); operationReturnType.Options |= CodeTypeReferenceOptions.GenericTypeParameter; invokeOperationType.TypeArguments.Add(operationReturnType); } // InvokeResults are wrapped in task (always) if (invokeKind == InvokeKind.Async) { invokeOperationType = new CodeTypeReference(typeof(Task).FullName, invokeOperationType); } CodeMemberMethod method = new CodeMemberMethod() { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = (invokeKind == InvokeKind.Async) ? (methodName + "Async") : methodName, ReturnType = invokeOperationType, }; this._proxyClass.Members.Add(method); ReadOnlyCollection <DomainOperationParameter> operationParameters = domainOperationEntry.Parameters; // Generate the <summary> doc comments string comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_DomainContext_Invoke_Method_Summary_Comment, domainOperationEntry.Name); method.Comments.AddRange(CodeGenUtilities.GenerateSummaryCodeComment(comment, this.ClientProxyGenerator.IsCSharp)); // Generate <param> doc comments foreach (DomainOperationParameter parameter in operationParameters) { comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_DomainContext_Invoke_Method_Parameter_Comment, parameter.Name); method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment(parameter.Name, comment, this.ClientProxyGenerator.IsCSharp)); } // Conditionally add the callback and userState <param> doc comments if (invokeKind == InvokeKind.WithCallback) { method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("callback", Resource.CodeGen_DomainContext_Invoke_Method_Callback_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("userState", Resource.CodeGen_DomainContext_Invoke_Method_UserState_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); } else if (invokeKind == InvokeKind.Async) { method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("cancellationToken", Resource.CodeGen_DomainContext_Invoke_Method_CancellationToken_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); } // Generate <returns> doc comments method.Comments.AddRange(CodeGenUtilities.GenerateReturnsCodeComment(Resource.CodeGen_DomainContext_Invoke_Returns_Comment, this.ClientProxyGenerator.IsCSharp)); // Propagate custom validation attributes from the DomainOperationEntry to this invoke operation. IEnumerable <Attribute> methodAttributes = domainOperationEntry.Attributes.Cast <Attribute>(); CustomAttributeGenerator.GenerateCustomAttributes( this.ClientProxyGenerator, this._proxyClass, ex => string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_ThrewException_CodeMethod, ex.Message, method.Name, this._proxyClass.Name, ex.InnerException.Message), methodAttributes, method.CustomAttributes, method.Comments); // ---------------------------------------------------------------- // generate invoke operation body: // return base.InvokeOperation<T>(methodName, typeof(T), parameters, hasSideEffects, callback, userState); // or return base.InvokeOperationAsync<T>(methodName, parameters, hasSideEffects); // ---------------------------------------------------------------- List <CodeExpression> invokeParams = new List <CodeExpression>(); invokeParams.Add(new CodePrimitiveExpression(methodName)); // add the return Type parameter if (invokeKind != InvokeKind.Async) { invokeParams.Add(new CodeTypeOfExpression(operationReturnType)); } // add any operation parameters CodeVariableReferenceExpression paramsRef = new CodeVariableReferenceExpression("parameters"); if (operationParameters.Count > 0) { // need to generate the user parameters dictionary CodeTypeReference dictionaryTypeReference = CodeGenUtilities.GetTypeReference( typeof(Dictionary <string, object>), this.ClientProxyGenerator, this._proxyClass); CodeVariableDeclarationStatement paramsDef = new CodeVariableDeclarationStatement( dictionaryTypeReference, "parameters", new CodeObjectCreateExpression(dictionaryTypeReference, Array.Empty <CodeExpression>())); method.Statements.Add(paramsDef); } foreach (DomainOperationParameter paramInfo in operationParameters) { // If this is an enum type, we need to ensure it is either shared or // can be generated. Failure to use this enum logs an error and exits. // The test for legality also causes the enum to be generated if required. Type enumType = TypeUtility.GetNonNullableType(paramInfo.ParameterType); if (enumType.IsEnum) { string errorMessage = null; if (!this.ClientProxyGenerator.CanExposeEnumType(enumType, out errorMessage)) { this.ClientProxyGenerator.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Domain_Op_Enum_Error, method.Name, this._proxyClass.Name, enumType.FullName, errorMessage)); return; } else { // Register use of this enum type, which could cause deferred generation this.ClientProxyGenerator.RegisterUseOfEnumType(enumType); } } // add the parameter to the method CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression( CodeGenUtilities.GetTypeReference( CodeGenUtilities.TranslateType(paramInfo.ParameterType), this.ClientProxyGenerator, this._proxyClass), paramInfo.Name); // Propagate parameter level validation attributes from domain operation entry IEnumerable <Attribute> paramAttributes = paramInfo.Attributes.Cast <Attribute>(); string commentHeader = string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_Parameter_FailedToGenerate, paramInfo.Name); CustomAttributeGenerator.GenerateCustomAttributes( this.ClientProxyGenerator, this._proxyClass, ex => string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_ThrewException_CodeMethodParameter, ex.Message, paramDecl.Name, method.Name, this._proxyClass.Name, ex.InnerException.Message), paramAttributes, paramDecl.CustomAttributes, method.Comments, commentHeader); method.Parameters.Add(paramDecl); // add the parameter and value to the params dictionary method.Statements.Add(new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(paramsRef, "Add"), new CodePrimitiveExpression(paramInfo.Name), new CodeVariableReferenceExpression(paramInfo.Name))); } // add parameters if present if (operationParameters.Count > 0) { invokeParams.Add(paramsRef); } else { invokeParams.Add(new CodePrimitiveExpression(null)); } InvokeAttribute invokeAttribute = (InvokeAttribute)domainOperationEntry.OperationAttribute; invokeParams.Add(new CodePrimitiveExpression(invokeAttribute.HasSideEffects)); switch (invokeKind) { case InvokeKind.WithCallback: { CodeTypeReference callbackType = CodeGenUtilities.GetTypeReference(typeof(Action).FullName, (string)this._proxyClass.UserData["Namespace"], false); callbackType.TypeArguments.Add(invokeOperationType); // add callback method parameter method.Parameters.Add(new CodeParameterDeclarationExpression(callbackType, "callback")); invokeParams.Add(new CodeVariableReferenceExpression("callback")); // add the userState parameter to the end method.Parameters.Add(new CodeParameterDeclarationExpression(CodeGenUtilities.GetTypeReference(typeof(object), this.ClientProxyGenerator, this._proxyClass), "userState")); invokeParams.Add(new CodeVariableReferenceExpression("userState")); } break; case InvokeKind.WithoutCallback: invokeParams.Add(new CodePrimitiveExpression(null)); invokeParams.Add(new CodePrimitiveExpression(null)); break; case InvokeKind.Async: var cancellationTokenType = CodeGenUtilities.GetTypeReference(typeof(CancellationToken), this.ClientProxyGenerator, this._proxyClass); var cancellationTokenParmeter = new CodeParameterDeclarationExpression(cancellationTokenType, "cancellationToken"); // For C# add " = default(CancellationToken)" // For VB add "Optional" ByVal .... = Nothing // otherwise fall back to adding [Optional] attribute, this is the same as adding "= default(CancellationToken)" if (ClientProxyGenerator.IsCSharp) { cancellationTokenParmeter.Name = string.Format("{0} = default({1})", cancellationTokenParmeter.Name, cancellationTokenType.BaseType); } else if (ClientProxyGenerator.IsVB) // VB { // Set an invalid field direction in order to have VB Code gen from generating cancellationTokenParmeter.Direction = (FieldDirection)0xff; cancellationTokenParmeter.Name = "Optional ByVal " + cancellationTokenParmeter.Name; cancellationTokenParmeter.Type = new CodeTypeReference(cancellationTokenType.BaseType + " = Nothing"); } else { // Add [Optional] attribute cancellationTokenParmeter.CustomAttributes.Add(new CodeAttributeDeclaration( CodeGenUtilities.GetTypeReference(typeof(OptionalAttribute), this.ClientProxyGenerator, this._proxyClass))); } method.Parameters.Add(cancellationTokenParmeter); invokeParams.Add(new CodeVariableReferenceExpression("cancellationToken")); break; } // this.ValidateMethod("methodName", parameters); CodeExpression paramsExpr = new CodePrimitiveExpression(null); if (operationParameters.Count > 0) { paramsExpr = paramsRef; } CodeExpressionStatement validateMethodCall = new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "ValidateMethod", new CodeExpression[] { new CodePrimitiveExpression(methodName), paramsExpr })); method.Statements.Add(validateMethodCall); var invokeMethod = (invokeKind == InvokeKind.Async) ? "InvokeOperationAsync" : "InvokeOperation"; var typeParameters = (domainOperationEntry.ReturnType == typeof(void)) ? Array.Empty <CodeTypeReference>() : new[] { operationReturnType }; var invokeMethodReference = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), invokeMethod, typeParameters); CodeExpression invokeCall = new CodeMethodInvokeExpression(invokeMethodReference, invokeParams.ToArray()); method.Statements.Add(new CodeMethodReturnStatement(invokeCall)); }
}//Usage() /// <summary> /// Gets user options. /// </summary> private static void GetOptions() { GetChannel: Console.Write("\nHttp (h), TCP (t) or both (b) using threads? "); string Reply = Console.ReadLine(); switch (Reply.ToLower()) { case "b": m_ChanKind = ChannelKind.Both; break; case "h": m_ChanKind = ChannelKind.Http; break; case "t": m_ChanKind = ChannelKind.TCP; break; default: Console.WriteLine("Invalid option, please try again."); goto GetChannel; }//switch GetConvention: Console.Write("\nBy ref (r) or by val (v)? "); Reply = Console.ReadLine(); switch (Reply.ToLower()) { case "r": m_CallConv = CallingConvention.ByRef; break; case "v": m_CallConv = CallingConvention.ByVal; break; default: Console.WriteLine("Invalid option, please try again."); goto GetConvention; }//switch GetInvoke: Console.Write("\nSerial (s) or async (a)? "); Reply = Console.ReadLine(); switch (Reply.ToLower()) { case "a": m_InvKind = InvokeKind.Async; break; case "s": m_InvKind = InvokeKind.Sequential; break; default: Console.WriteLine("Invalid option, please try again."); goto GetInvoke; }//switch //Setup the correct Type object to pass to the Client object for object creation. switch (m_CallConv) { case CallingConvention.ByRef: m_ObjType = Type.GetType("RemotingSamples.HelloServerByRef,remotingshared"); break; case CallingConvention.ByVal: m_ObjType = Type.GetType("RemotingSamples.HelloServerByVal,remotingshared"); break; default: throw new System.InvalidOperationException("Invalid Calling Convention in Main()"); }//switch Console.WriteLine(); return; }//GetOptions()
private void GenerateInvokeOperationDeclaration(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { // First generate custom attributes for the qery method IEnumerable <Attribute> methodAttributes = domainOperationEntry.Attributes.Cast <Attribute>(); this.GenerateAttributes(methodAttributes); string invokeOperationReturnTypeName = this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind); var name = domainOperationEntry.Name; if (invokeKind == InvokeKind.Async) { name = name + "Async"; } this.Write("public "); this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); this.Write(" "); this.Write(this.ToStringHelper.ToStringWithCulture(name)); this.Write("(\r\n"); this.GenerateParameterDeclaration(domainOperationEntry.Parameters, true); if (invokeKind == InvokeKind.WithCallback) { if (domainOperationEntry.Parameters.Count() > 0) { this.Write(", "); } this.Write("Action<"); this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); this.Write("> callback, object userState\r\n"); } else if (invokeKind == InvokeKind.Async) { if (domainOperationEntry.Parameters.Count() > 0) { this.Write(", "); } this.Write("System.Threading.CancellationToken cancellationToken = default (System.Threading." + "CancellationToken)\r\n"); } this.Write(")\r\n"); }
private void GenerateInvokeMethodReturn(DomainOperationEntry domainOperationEntry, string parameterDictionaryString, InvokeKind invokeKind) { InvokeAttribute invokeAttribute = (InvokeAttribute)domainOperationEntry.OperationAttribute; string returnTypeNameString = CodeGenUtilities.GetTypeName(CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType)); if(invokeKind == InvokeKind.Async) { returnTypeNameString = (domainOperationEntry.ReturnType == typeof(void)) ? string.Empty : string.Format("<{0}>", returnTypeNameString); #line default #line hidden #line 92 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("return this.InvokeOperationAsync"); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("(\""); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("\", "); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); #line default #line hidden #line 93 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(", \r\n"); #line default #line hidden #line 94 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); #line default #line hidden #line 94 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(");\r\n"); #line default #line hidden #line 95 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" } else { #line default #line hidden #line 99 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("return this."); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind))); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("(\""); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("\", typeof("); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("), "); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); #line default #line hidden #line 100 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(", \r\n"); #line default #line hidden #line 101 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); #line default #line hidden #line 101 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(",\r\n"); #line default #line hidden #line 102 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" if(invokeKind == InvokeKind.WithCallback) { #line default #line hidden #line 105 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("callback, userState);\r\n"); #line default #line hidden #line 107 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" } else { #line default #line hidden #line 111 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("null, null);\r\n"); #line default #line hidden #line 113 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" } } }
private void GenerateInvokeOperationDeclaration(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { // First generate custom attributes for the qery method IEnumerable<Attribute> methodAttributes = domainOperationEntry.Attributes.Cast<Attribute>(); this.GenerateAttributes(methodAttributes); string invokeOperationReturnTypeName = this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind); var name = domainOperationEntry.Name; if(invokeKind == InvokeKind.Async) name = name + "Async"; #line default #line hidden #line 59 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("public "); #line default #line hidden #line 60 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); #line default #line hidden #line 60 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(" "); #line default #line hidden #line 60 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(name)); #line default #line hidden #line 60 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("(\r\n"); #line default #line hidden #line 61 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.GenerateParameterDeclaration(domainOperationEntry.Parameters, true); if(invokeKind == InvokeKind.WithCallback) { if(domainOperationEntry.Parameters.Count() > 0) { #line default #line hidden #line 68 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(", "); #line default #line hidden #line 68 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" } #line default #line hidden #line 70 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("Action<"); #line default #line hidden #line 71 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(this.ToStringHelper.ToStringWithCulture(invokeOperationReturnTypeName)); #line default #line hidden #line 71 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write("> callback, object userState\r\n"); #line default #line hidden #line 72 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" } #line default #line hidden #line 74 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" this.Write(")\r\n"); #line default #line hidden #line 75 "C:\Code\Repos\openriaservices\OpenRiaServices.DomainServices.Tools.TextTemplate\Framework\CSharpGenerators\Templates\InvokeOperationProxyGeneratorTemplate.ttinclude" }
internal string GetInvokeMethodReturnTypeName(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { Type returnType = CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType); string returnTypeString = (invokeKind == InvokeKind.Async) ? "InvokeResult" : "InvokeOperation"; if (returnType != typeof (void)) { if (!this.RegisterEnumTypeIfNecessary(returnType, domainOperationEntry)) { return String.Empty; } returnTypeString = returnTypeString + "<" + CodeGenUtilities.GetTypeName(returnType) + ">"; } if (invokeKind == InvokeKind.Async) returnTypeString = string.Format("System.Threading.Tasks.Task<{0}>", returnTypeString); return returnTypeString; }
private void GenerateInvokeMethodReturn(DomainOperationEntry domainOperationEntry, string parameterDictionaryString, InvokeKind invokeKind) { InvokeAttribute invokeAttribute = (InvokeAttribute)domainOperationEntry.OperationAttribute; string returnTypeNameString = CodeGenUtilities.GetTypeName(CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType)); if (invokeKind == InvokeKind.Async) { returnTypeNameString = (domainOperationEntry.ReturnType == typeof(void)) ? string.Empty : string.Format("<{0}>", returnTypeNameString); this.Write("return this.InvokeOperationAsync"); this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); this.Write("(\""); this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); this.Write("\", "); this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); this.Write(", \r\n"); this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); this.Write(", cancellationToken);\r\n"); } else { this.Write("return this."); this.Write(this.ToStringHelper.ToStringWithCulture(this.GetInvokeMethodReturnTypeName(domainOperationEntry, invokeKind))); this.Write("(\""); this.Write(this.ToStringHelper.ToStringWithCulture(domainOperationEntry.Name)); this.Write("\", typeof("); this.Write(this.ToStringHelper.ToStringWithCulture(returnTypeNameString)); this.Write("), "); this.Write(this.ToStringHelper.ToStringWithCulture(parameterDictionaryString)); this.Write(", \r\n"); this.Write(this.ToStringHelper.ToStringWithCulture(CodeGenUtilities.GetBooleanString(invokeAttribute.HasSideEffects, true))); this.Write(",\r\n"); if (invokeKind == InvokeKind.WithCallback) { this.Write("callback, userState);\r\n"); } else { this.Write("null, null);\r\n"); } } }
/// <summary> /// Generates an invoke operation. /// </summary> /// <param name="domainOperationEntry">The invoke operation.</param> /// <param name="invokeKind">the type of invoke method to generate.</param> private void GenerateInvokeOperation(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind) { // Determine the name of the generated invoke function string methodName = domainOperationEntry.Name; // ---------------------------------------------------------------- // Check for name conflicts // ---------------------------------------------------------------- if ((invokeKind == InvokeKind.WithCallback) && this._proxyClass.Members.Cast<CodeTypeMember>().Any(c => c.Name == methodName && c.GetType() != typeof(CodeMemberMethod))) { this.ClientProxyGenerator.LogError( string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_NamingCollision_MemberAlreadyExists, this._proxyClass.Name, methodName)); return; } // ---------------------------------------------------------------- // InvokeResult<T> InvokeOperation(args); // // InvokeResult<T> InvokeOperation(args, callback, userState); // // Task<T> InvokeOperationAsync(args); // ---------------------------------------------------------------- CodeTypeReference operationReturnType = null; Type returnType = CodeGenUtilities.TranslateType(domainOperationEntry.ReturnType); var methodReturnTypeName = (invokeKind == InvokeKind.Async) ? TypeConstants.InvokeResultTypeFullName: TypeConstants.InvokeOperationTypeFullName; CodeTypeReference invokeOperationType = CodeGenUtilities.GetTypeReference(methodReturnTypeName, (string)this._proxyClass.UserData["Namespace"], false); if (returnType != typeof(void)) { // If this is an enum type, we need to ensure it is either shared or // can be generated. Failure to use this enum is only a warning and causes // this invoke operation to be skipped. The test for legality also causes // the enum to be generated if required. Type enumType = TypeUtility.GetNonNullableType(returnType); if (enumType.IsEnum) { string errorMessage = null; if (!this.ClientProxyGenerator.CanExposeEnumType(enumType, out errorMessage)) { this.ClientProxyGenerator.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Domain_Op_Enum_Error, methodName, this._proxyClass.Name, enumType.FullName, errorMessage)); return; } else { // Register use of this enum type, which could cause deferred generation this.ClientProxyGenerator.RegisterUseOfEnumType(enumType); } } operationReturnType = CodeGenUtilities.GetTypeReference(returnType, this.ClientProxyGenerator, this._proxyClass); operationReturnType.Options |= CodeTypeReferenceOptions.GenericTypeParameter; invokeOperationType.TypeArguments.Add(operationReturnType); } // InvokeResults are wrapped in task (always) if (invokeKind == InvokeKind.Async) { invokeOperationType = new CodeTypeReference(typeof(Task).FullName, invokeOperationType); } CodeMemberMethod method = new CodeMemberMethod() { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = (invokeKind == InvokeKind.Async) ? (methodName + "Async") : methodName, ReturnType = invokeOperationType, }; this._proxyClass.Members.Add(method); ReadOnlyCollection<DomainOperationParameter> operationParameters = domainOperationEntry.Parameters; // Generate the <summary> doc comments string comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_DomainContext_Invoke_Method_Summary_Comment, domainOperationEntry.Name); method.Comments.AddRange(CodeGenUtilities.GenerateSummaryCodeComment(comment, this.ClientProxyGenerator.IsCSharp)); // Generate <param> doc comments foreach (DomainOperationParameter parameter in operationParameters) { comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_DomainContext_Invoke_Method_Parameter_Comment, parameter.Name); method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment(parameter.Name, comment, this.ClientProxyGenerator.IsCSharp)); } // Conditionally add the callback and userState <param> doc comments if (invokeKind == InvokeKind.WithCallback) { method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("callback", Resource.CodeGen_DomainContext_Invoke_Method_Callback_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("userState", Resource.CodeGen_DomainContext_Invoke_Method_UserState_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); } else if(invokeKind == InvokeKind.Async) { method.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("cancellationToken", Resource.CodeGen_DomainContext_Invoke_Method_CancellationToken_Parameter_Comment, this.ClientProxyGenerator.IsCSharp)); } // Generate <returns> doc comments method.Comments.AddRange(CodeGenUtilities.GenerateReturnsCodeComment(Resource.CodeGen_DomainContext_Invoke_Returns_Comment, this.ClientProxyGenerator.IsCSharp)); // Propagate custom validation attributes from the DomainOperationEntry to this invoke operation. IEnumerable<Attribute> methodAttributes = domainOperationEntry.Attributes.Cast<Attribute>(); CustomAttributeGenerator.GenerateCustomAttributes( this.ClientProxyGenerator, this._proxyClass, ex => string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_ThrewException_CodeMethod, ex.Message, method.Name, this._proxyClass.Name, ex.InnerException.Message), methodAttributes, method.CustomAttributes, method.Comments); // ---------------------------------------------------------------- // generate invoke operation body: // return base.InvokeOperation<T>(methodName, typeof(T), parameters, hasSideEffects, callback, userState); // or return base.InvokeOperationAsync<T>(methodName, parameters, hasSideEffects); // ---------------------------------------------------------------- List<CodeExpression> invokeParams = new List<CodeExpression>(); invokeParams.Add(new CodePrimitiveExpression(methodName)); // add the return Type parameter if (invokeKind != InvokeKind.Async) invokeParams.Add(new CodeTypeOfExpression(operationReturnType)); // add any operation parameters CodeVariableReferenceExpression paramsRef = new CodeVariableReferenceExpression("parameters"); if (operationParameters.Count > 0) { // need to generate the user parameters dictionary CodeTypeReference dictionaryTypeReference = CodeGenUtilities.GetTypeReference( typeof(Dictionary<string, object>), this.ClientProxyGenerator, this._proxyClass); CodeVariableDeclarationStatement paramsDef = new CodeVariableDeclarationStatement( dictionaryTypeReference, "parameters", new CodeObjectCreateExpression(dictionaryTypeReference, new CodeExpression[0])); method.Statements.Add(paramsDef); } foreach (DomainOperationParameter paramInfo in operationParameters) { // If this is an enum type, we need to ensure it is either shared or // can be generated. Failure to use this enum logs an error and exits. // The test for legality also causes the enum to be generated if required. Type enumType = TypeUtility.GetNonNullableType(paramInfo.ParameterType); if (enumType.IsEnum) { string errorMessage = null; if (!this.ClientProxyGenerator.CanExposeEnumType(enumType, out errorMessage)) { this.ClientProxyGenerator.LogError(string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Domain_Op_Enum_Error, method.Name, this._proxyClass.Name, enumType.FullName, errorMessage)); return; } else { // Register use of this enum type, which could cause deferred generation this.ClientProxyGenerator.RegisterUseOfEnumType(enumType); } } // add the parameter to the method CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression( CodeGenUtilities.GetTypeReference( CodeGenUtilities.TranslateType(paramInfo.ParameterType), this.ClientProxyGenerator, this._proxyClass), paramInfo.Name); // Propagate parameter level validation attributes from domain operation entry IEnumerable<Attribute> paramAttributes = paramInfo.Attributes.Cast<Attribute>(); string commentHeader = string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_Parameter_FailedToGenerate, paramInfo.Name); CustomAttributeGenerator.GenerateCustomAttributes( this.ClientProxyGenerator, this._proxyClass, ex => string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_ThrewException_CodeMethodParameter, ex.Message, paramDecl.Name, method.Name, this._proxyClass.Name, ex.InnerException.Message), paramAttributes, paramDecl.CustomAttributes, method.Comments, commentHeader); method.Parameters.Add(paramDecl); // add the parameter and value to the params dictionary method.Statements.Add(new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(paramsRef, "Add"), new CodePrimitiveExpression(paramInfo.Name), new CodeVariableReferenceExpression(paramInfo.Name))); } // add parameters if present if (operationParameters.Count > 0) { invokeParams.Add(paramsRef); } else { invokeParams.Add(new CodePrimitiveExpression(null)); } InvokeAttribute invokeAttribute = (InvokeAttribute)domainOperationEntry.OperationAttribute; invokeParams.Add(new CodePrimitiveExpression(invokeAttribute.HasSideEffects)); switch (invokeKind) { case InvokeKind.WithCallback: { CodeTypeReference callbackType = CodeGenUtilities.GetTypeReference(typeof(Action).FullName, (string)this._proxyClass.UserData["Namespace"], false); callbackType.TypeArguments.Add(invokeOperationType); // add callback method parameter method.Parameters.Add(new CodeParameterDeclarationExpression(callbackType, "callback")); invokeParams.Add(new CodeVariableReferenceExpression("callback")); // add the userState parameter to the end method.Parameters.Add(new CodeParameterDeclarationExpression(CodeGenUtilities.GetTypeReference(typeof(object), this.ClientProxyGenerator, this._proxyClass), "userState")); invokeParams.Add(new CodeVariableReferenceExpression("userState")); } break; case InvokeKind.WithoutCallback: invokeParams.Add(new CodePrimitiveExpression(null)); invokeParams.Add(new CodePrimitiveExpression(null)); break; case InvokeKind.Async: var cancellationTokenType = CodeGenUtilities.GetTypeReference(typeof (CancellationToken), this.ClientProxyGenerator,this._proxyClass); var cancellationTokenParmeter = new CodeParameterDeclarationExpression(cancellationTokenType, "cancellationToken"); // For C# add " = default(CancellationToken)" // For VB add "Optional" ByVal .... = Nothing // otherwise fall back to adding [Optional] attribute, this is the same as adding "= default(CancellationToken)" if (ClientProxyGenerator.IsCSharp) { cancellationTokenParmeter.Name = string.Format("{0} = default({1})", cancellationTokenParmeter.Name, cancellationTokenType.BaseType); } else if (ClientProxyGenerator.IsVB) // VB { // Set an invalid field direction in order to have VB Code gen from generating cancellationTokenParmeter.Direction = (FieldDirection)0xff; cancellationTokenParmeter.Name = "Optional ByVal " + cancellationTokenParmeter.Name; cancellationTokenParmeter.Type = new CodeTypeReference(cancellationTokenType.BaseType + " = Nothing"); } else { // Add [Optional] attribute cancellationTokenParmeter.CustomAttributes.Add(new CodeAttributeDeclaration( CodeGenUtilities.GetTypeReference(typeof(OptionalAttribute), this.ClientProxyGenerator, this._proxyClass))); } method.Parameters.Add(cancellationTokenParmeter); invokeParams.Add(new CodeVariableReferenceExpression("cancellationToken")); break; } // this.ValidateMethod("methodName", parameters); CodeExpression paramsExpr = new CodePrimitiveExpression(null); if (operationParameters.Count > 0) { paramsExpr = paramsRef; } CodeExpressionStatement validateMethodCall = new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "ValidateMethod", new CodeExpression[] { new CodePrimitiveExpression(methodName), paramsExpr })); method.Statements.Add(validateMethodCall); var invokeMethod = (invokeKind == InvokeKind.Async) ? "InvokeOperationAsync" : "InvokeOperation"; var typeParameters = (domainOperationEntry.ReturnType == typeof(void)) ? new CodeTypeReference[0] : new[] { operationReturnType }; var invokeMethodReference = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), invokeMethod, typeParameters); CodeExpression invokeCall = new CodeMethodInvokeExpression(invokeMethodReference, invokeParams.ToArray()); method.Statements.Add(new CodeMethodReturnStatement(invokeCall)); }