internal static string ConvertParametersToCsv(CodeExpressionCollection parameters) { if (parameters.Count == 0) { return("None"); } string output = parameters.Cast <CodeExpression>().Aggregate(string.Empty, (current, expression) => current + (ConvertCodeExpression(expression) + " ")); return(output.TrimEnd().Replace(" ", ", ")); }
private void GenerateMethod(IDLInterface idlIntf, IDLMethod idlMethod , Udbus.Parsing.ICodeTypeDeclarationHolder contextDeclarationHolder , CodeTypeReference typerefDbusInterface , CodeTypeReference typerefDbusMarshal , CodeTypeDeclaration typeProxy) { // Straight-forward interface method. CodeMemberMethod methodInterface = new CodeMemberMethod(); CodeExpressionCollection interfaceCallArgs = new CodeExpressionCollection(); methodInterface.Name = idlMethod.Name; methodInterface.Attributes = MemberAttributes.Public; Udbus.Parsing.BuildContext context = new Udbus.Parsing.BuildContext(contextDeclarationHolder); #region Methods args foreach (IDLMethodArgument idlMethodArg in idlMethod.Arguments) { CodeCommentStatement commentMethod = new CodeCommentStatement(string.Format("{0} {1} \"{2}\"", idlMethodArg.Direction, idlMethodArg.Name, idlMethodArg.Type)); methodInterface.Comments.Add(commentMethod); // Parse the type string for the argument, creating required structs as we go, and returning a type for the argument. Udbus.Parsing.IDLArgumentTypeNameBuilderBase nameBuilder = new IDLMethodArgumentTypeNameBuilder(idlIntf, idlMethod); ParamCodeTypeFactory paramtypeHolder = new ParamCodeTypeFactory(CodeTypeFactory.Default, idlMethodArg.Direction == "out" ? FieldDirection.Out : FieldDirection.In); Udbus.Parsing.CodeBuilderHelper.BuildCodeParamType(paramtypeHolder, nameBuilder, idlMethodArg.Type, context); Udbus.Parsing.ICodeParamType paramtype = paramtypeHolder.paramtype; // Arguments. CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(paramtype.CodeType, idlMethodArg.Name); CodeVariableReferenceExpression varrefMethodArg = new CodeVariableReferenceExpression(idlMethodArg.Name); if (idlMethodArg.Direction == "out") { // Add to interface parameters. interfaceCallArgs.Add(new CodeDirectionExpression(FieldDirection.Out, varrefMethodArg)); // Add parameter to interface method. param.Direction = FieldDirection.Out; } else { interfaceCallArgs.Add(varrefMethodArg); } methodInterface.Parameters.Add(param); } // Ends loop over method arguments #endregion methodInterface.Statements.Add(this.DeclareTargetVariable(typerefDbusInterface, typerefDbusMarshal)); methodInterface.Statements.Add(new CodeMethodInvokeExpression(varrefTarget, idlMethod.Name, interfaceCallArgs.Cast <CodeExpression>().ToArray())); //methodInterface.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(thisProxyFieldRef, idlMethod.Name) // , interfaceCallArgs.Cast<CodeExpression>().ToArray() //)); // Finish up. typeProxy.Members.Add(methodInterface); }
public override void GenerateMethods(IDLInterface idlIntf) { if (idlIntf.Methods != null) // If got methods { bAddNamespace = idlIntf.Methods.Count > 0; foreach (IDLMethod idlMethod in idlIntf.Methods) { // Structs for capturing input/output from method. Udbus.Parsing.CodeTypeDeferredStructHolder paramsHolder = new Udbus.Parsing.CodeTypeDeferredStructHolder(idlMethod.Name + "AsyncParams"); Udbus.Parsing.CodeTypeDeferredStructHolder resultHolder = new Udbus.Parsing.CodeTypeDeferredStructHolder(idlMethod.Name + "AsyncResult"); CodeConstructor constructorResults = new CodeConstructor(); CodeConstructor constructorParams = new CodeConstructor(); constructorResults.Attributes = constructorParams.Attributes = MemberAttributes.Public; // Create Call method. CodeMemberMethod methodCall = new CodeMemberMethod(); methodCall.Name = "Call" + idlMethod.Name; // Actual call to proxy arguments will be added to as we parse IDL arguments. CodeExpressionCollection callParameters = new CodeExpressionCollection(); CodeExpressionCollection callResultArgs = new CodeExpressionCollection(); CodeExpressionCollection interfaceCallArgs = new CodeExpressionCollection(); CodeArgumentReferenceExpression argrefCallData = new CodeArgumentReferenceExpression(dataName); // Event Args string eventName = idlMethod.Name + "EventArgs"; CodeTypeDeclaration typeEvent = new CodeTypeDeclaration(eventName); typeEvent.IsClass = true; typeEvent.TypeAttributes = TypeAttributes.Public; typeEvent.BaseTypes.Add(new CodeTypeReference(typeof(AsyncCompletedEventArgs))); CodeConstructor constructorEventArgs = new CodeConstructor(); eventsDeclarationHolder.Add(typeEvent); CodeExpressionCollection makeEventArgs = new CodeExpressionCollection(); // Event Raiser... string raiserName = "raiser" + idlMethod.Name; CodeTypeReference raiserRef = new CodeTypeReference("AsyncOperationEventRaiser", new CodeTypeReference(eventName)); CodeMemberField fieldRaiser = new CodeMemberField(raiserRef, raiserName); fieldRaiser.InitExpression = new CodeObjectCreateExpression(raiserRef); fieldRaiser.Attributes = MemberAttributes.Private; typeProxy.Members.Add(fieldRaiser); // Event raiser EventCompleted Property - unfortunately CodeMemberEvent is useless here since can't add custom add/remove. // So anything other than CSharp is now a bust. Brilliant. CodeSnippetTypeMember eventRaiser = new CodeSnippetTypeMember(); eventRaiser.Text = string.Format(@" public event System.EventHandler<{0}> {1}Completed {{ add {{ this.{2}.CompletedEvent += value; }} remove {{ this.{2}.CompletedEvent -= value; }} }} ", eventName, idlMethod.Name, raiserName ); // Adding text here. //CodeMemberEvent eventRaiser = new CodeMemberEvent(); //eventRaiser.Attributes = MemberAttributes.Public; //CodeParamDeclaredType declaredType = new CodeParamDeclaredType(typeEvent); //eventRaiser.Type = new CodeTypeReference(CodeBuilderCommon.EventHandlerType.Name, declaredType.CodeType); //eventRaiser.Name = idlMethod.Name + "Completed"; typeProxy.Members.Add(eventRaiser); // Async method. CodeMemberMethod methodAsync = new CodeMemberMethod(); methodAsync.Name = idlMethod.Name + "Async"; methodAsync.Attributes = MemberAttributes.Public; // Straight-forward interface method. CodeMemberMethod methodInterface = new CodeMemberMethod(); methodInterface.Name = idlMethod.Name; methodInterface.Attributes = MemberAttributes.Public; // CodeComment commentMethod = new CodeComment(idlMethod.Name); // method.Comments.Add(new CodeCommentStatement(idlMethod.Name)); CodeExpressionCollection asyncArgs = new CodeExpressionCollection(); Udbus.Parsing.BuildContext context = new Udbus.Parsing.BuildContext(contextDeclarationHolder); foreach (IDLMethodArgument idlMethodArg in idlMethod.Arguments) { CodeCommentStatement commentMethod = new CodeCommentStatement(string.Format("{0} {1} \"{2}\"", idlMethodArg.Direction, idlMethodArg.Name, idlMethodArg.Type)); methodAsync.Comments.Add(commentMethod); methodInterface.Comments.Add(commentMethod); // Parse the type string for the argument, creating required structs as we go, and returning a type for the argument. Udbus.Parsing.IDLArgumentTypeNameBuilderBase nameBuilder = new IDLMethodArgumentTypeNameBuilder(idlIntf, idlMethod); ParamCodeTypeFactory paramtypeHolder = new ParamCodeTypeFactory(CodeTypeFactory.Default, idlMethodArg.Direction == "out" ? FieldDirection.Out : FieldDirection.In); Udbus.Parsing.CodeBuilderHelper.BuildCodeParamType(paramtypeHolder, nameBuilder, idlMethodArg.Type, context); Udbus.Parsing.ICodeParamType paramtype = paramtypeHolder.paramtype; // Arguments. CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(paramtype.CodeType, idlMethodArg.Name); CodeVariableReferenceExpression varrefMethodArg = new CodeVariableReferenceExpression(idlMethodArg.Name); if (idlMethodArg.Direction == "out") // If out argument { // Add to interface parameters. interfaceCallArgs.Add(new CodeDirectionExpression(FieldDirection.Out, varrefMethodArg)); // Put into result holding struct... param.Direction = FieldDirection.Out; methodInterface.Parameters.Add(param); CodeTypeReference argType = CodeBuilderCommon.GetReadOnlyCodeReference(paramtypeHolder.paramtype.CodeType); CodeMemberField fieldResultArg = new CodeMemberField(argType, idlMethodArg.Name); fieldResultArg.Attributes = MemberAttributes.Public; resultHolder.CodeType.Members.Add(fieldResultArg); constructorResults.Parameters.Add(new CodeParameterDeclarationExpression(paramtype.CodeType, idlMethodArg.Name)); CodeFieldReferenceExpression thisArg = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), idlMethodArg.Name ); constructorResults.Statements.Add(new CodeAssignStatement(thisArg, new CodeArgumentReferenceExpression(idlMethodArg.Name))); // Add placeholder variables to call method. methodCall.Statements.Add(new CodeVariableDeclarationStatement(paramtype.CodeType, idlMethodArg.Name)); // Add appropriate parameter in actual call to interface. callParameters.Add(new CodeDirectionExpression(FieldDirection.Out, varrefMethodArg)); // Add appropriate parameter in call to result constructor. callResultArgs.Add(new CodeArgumentReferenceExpression(idlMethodArg.Name)); // Put into event args class... string fieldEventArgName = idlMethodArg.Name + "_"; CodeMemberField fieldEventArg = new CodeMemberField(paramtype.CodeType, fieldEventArgName); fieldEventArg.Attributes = MemberAttributes.Private; typeEvent.Members.Add(fieldEventArg); // Add argument property to EventArgs. CodeMemberProperty propEventArg = new CodeMemberProperty(); propEventArg.Attributes = MemberAttributes.Public | MemberAttributes.Final; propEventArg.Name = idlMethodArg.Name; propEventArg.HasGet = true; propEventArg.Type = paramtype.CodeType; propEventArg.GetStatements.Add(new CodeMethodInvokeExpression(null, "RaiseExceptionIfNecessary")); propEventArg.GetStatements.Add(new CodeMethodReturnStatement(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), fieldEventArgName))); typeEvent.Members.Add(propEventArg); // Add constructor parameter and statement to EventArgs. constructorEventArgs.Parameters.Add(new CodeParameterDeclarationExpression(paramtype.CodeType, idlMethodArg.Name)); constructorEventArgs.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldEventArgName), new CodeArgumentReferenceExpression(idlMethodArg.Name) )); // Add as parameter in call to EventArgs constructor. makeEventArgs.Add(new CodeFieldReferenceExpression(new CodeArgumentReferenceExpression(resultName), idlMethodArg.Name)); } // Ends if out argument else // Else in argument { // Add to interface parameters. interfaceCallArgs.Add(varrefMethodArg); // Put into parameter holding struct. CodeMemberField fieldArg = new CodeMemberField(CodeBuilderCommon.GetReadOnlyCodeReference(paramtype.CodeType), idlMethodArg.Name); fieldArg.Attributes = MemberAttributes.Public; paramsHolder.CodeType.Members.Add(fieldArg); constructorParams.Parameters.Add(new CodeParameterDeclarationExpression(paramtype.CodeType, idlMethodArg.Name)); CodeFieldReferenceExpression thisArg = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), idlMethodArg.Name ); constructorParams.Statements.Add(new CodeAssignStatement(thisArg, new CodeArgumentReferenceExpression(idlMethodArg.Name))); // Add appropriate parameter in actual call to interface. callParameters.Add(new CodeFieldReferenceExpression(argrefCallData, idlMethodArg.Name)); // Add appropriate parameter to async method parameters constructor call. asyncArgs.Add(new CodeArgumentReferenceExpression(idlMethodArg.Name)); // Add parameter to async method. methodAsync.Parameters.Add(param); // Add parameter to interface method. methodInterface.Parameters.Add(param); } // Ends else in argument } // Ends loop over method arguments methodAsync.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "userState")); // Add method body, then sort out arguments code... CodeFieldReferenceExpression thisRaiser = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), raiserName ); CodeTypeReference typerefResult = null; if (idlMethod.Return != null) // If method has return type { // Add result to Result type. // TODO replace typeof(string) with actual return type. typerefResult = new CodeTypeReference("???"); } CodeTypeReference typerefResults = null; CodeTypeReference typerefParams = null; CodeExpression exprAsyncParamValue = null; string asyncMethodName = "AsyncFuncImpl"; // Default is assuming that function returns something. if (paramsHolder.QuType()) // If got params type { typerefParams = new CodeTypeReference(paramsHolder.CodeType.Name); // Add proxy field to params struct. CodeMemberField memberParamsProxy = new CodeMemberField(new CodeTypeReference("readonly " + genInterfaceName), proxyName); memberParamsProxy.Attributes = MemberAttributes.Public; paramsHolder.CodeType.Members.Insert(0, memberParamsProxy); // TODO: Going to need a using or a fully qualified name. // Add initialisation to constructor constructorParams.Parameters.Insert(0, paramProxy); // Constructor will take proxy as first argument. constructorParams.Statements.Insert(0, assignProxy); paramsHolder.CodeType.TypeAttributes = TypeAttributes.NestedPrivate; paramsHolder.CodeType.IsStruct = true; constructorParams.Attributes = MemberAttributes.Public; paramsHolder.CodeType.Members.Add(constructorParams); typeProxy.Members.Add(paramsHolder.CodeType); asyncArgs.Insert(0, thisProxyFieldRef); exprAsyncParamValue = new CodeObjectCreateExpression(typerefParams, asyncArgs.Cast <CodeExpression>().ToArray()); } // Ends if got params type if (resultHolder.QuType()) // If got results type { typerefResults = new CodeTypeReference(resultHolder.CodeType.Name); methodCall.ReturnType = typerefResults; // Setup call method parameters. if (idlMethod.Return != null) { // Add result field to EventArgs. CodeMemberField fieldResult = new CodeMemberField(typerefResult, resultName); fieldResult.Attributes = MemberAttributes.Private; typeEvent.Members.Insert(0, fieldResult); // Add result property to EventArgs. CodeMemberProperty propResult = new CodeMemberProperty(); propResult.Attributes = MemberAttributes.Public; propResult.Name = resultName; propResult.HasGet = true; propResult.Type = typerefResult; propResult.GetStatements.Add(new CodeMethodInvokeExpression(null, "RaiseExceptionIfNecessary")); propResult.GetStatements.Add(new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), resultName)); typeEvent.Members.Add(propResult); // Add suitable parameter as first EventArgs constructor argument. constructorEventArgs.Parameters.Insert(0, new CodeParameterDeclarationExpression(typerefResult, resultName)); // Add statement to initialise result member. CodeFieldReferenceExpression thisArg = new CodeFieldReferenceExpression( new CodeThisReferenceExpression(), resultName ); // Include result in parameters to EventArgs in MakeEventArgs statements. makeEventArgs.Insert(0, new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), resultName)); // Add result to Result type. CodeTypeReference typerefReadOnlyResult = CodeBuilderCommon.GetReadOnlyCodeReference(typerefResult); CodeMemberField fieldReadOnlyResult = new CodeMemberField(typerefReadOnlyResult, resultName); fieldResult.Attributes = MemberAttributes.Public; resultHolder.CodeType.Members.Insert(0, fieldReadOnlyResult); // Add suitable parameter as first constructor argument. constructorResults.Parameters.Insert(0, new CodeParameterDeclarationExpression(typerefResult, resultName)); // Add statement to initialise result member. constructorResults.Statements.Insert(0, new CodeAssignStatement(thisArg, new CodeArgumentReferenceExpression(resultName))); } // End if there is a return statement resultHolder.CodeType.TypeAttributes = TypeAttributes.NestedPrivate; resultHolder.CodeType.IsStruct = true; resultHolder.CodeType.Members.Add(constructorResults); typeProxy.Members.Add(resultHolder.CodeType); } // Ends if got results type else // Else no results type { // Absolutely no results (including out parameters) means it's an Action. asyncMethodName = "AsyncActionImpl"; } // Ends else no results type // Time to bite the bullet. CodeTypeReference typerefEvent = new CodeTypeReference(typeEvent.Name); CodeMemberMethod methodMakeEventArgs = new CodeMemberMethod(); methodMakeEventArgs.Name = "Make" + idlMethod.Name + "AsyncEventArgs"; // Add missing parameters to EventArgs... constructorEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclException); constructorEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclCancelled); constructorEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclUserState); // Pass through to base class. constructorEventArgs.BaseConstructorArgs.Add(CodeBuilderCommon.argrefException); constructorEventArgs.BaseConstructorArgs.Add(CodeBuilderCommon.argrefCancelled); constructorEventArgs.BaseConstructorArgs.Add(CodeBuilderCommon.argrefUserState); // Add MakeEventArgs method... // Create MakeEventArgs method. methodMakeEventArgs.Attributes = MemberAttributes.Private | MemberAttributes.Static; if (typerefParams != null) // If got params type { methodMakeEventArgs.Parameters.Add(new CodeParameterDeclarationExpression(typerefParams, dataName)); } else // Else no params type { // The interface will be passed as the first parameter. methodMakeEventArgs.Parameters.Add(paramProxy); } // Ends else no params type if (typerefResults != null) // If got results type { methodMakeEventArgs.Parameters.Add(new CodeParameterDeclarationExpression(typerefResults, resultName)); } methodMakeEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclException); methodMakeEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclCancelled); methodMakeEventArgs.Parameters.Add(CodeBuilderCommon.paramdeclUserState); makeEventArgs.Add(CodeBuilderCommon.argrefException); makeEventArgs.Add(CodeBuilderCommon.argrefCancelled); makeEventArgs.Add(CodeBuilderCommon.argrefUserState); methodMakeEventArgs.Statements.Add(new CodeMethodReturnStatement( new CodeObjectCreateExpression( typerefEvent, makeEventArgs.Cast <CodeExpression>().ToArray() ) )); methodMakeEventArgs.ReturnType = typerefEvent; typeProxy.Members.Add(methodMakeEventArgs); // Setup call method parameters. methodCall.Attributes = MemberAttributes.Private | MemberAttributes.Static; CodeExpression exprProxyRef; //methodCall.ReturnType = new CodeTypeReference(resultHolder.CodeType.Name); if (typerefParams != null) // If passing parameters { methodCall.Parameters.Add(new CodeParameterDeclarationExpression(typerefParams, dataName)); exprProxyRef = new CodeFieldReferenceExpression(argrefCallData, proxyName); } // Ends if passing parameters else // Else just passing proxy { methodCall.Parameters.Add(new CodeParameterDeclarationExpression(genInterfaceName, proxyName)); exprProxyRef = new CodeArgumentReferenceExpression(proxyName); } // Ends else just passing proxy // Add call method body... // Invocation to proxy. CodeMethodReferenceExpression methodProxy = new CodeMethodReferenceExpression(exprProxyRef, idlMethod.Name); CodeMethodInvokeExpression invokeProxy = new CodeMethodInvokeExpression(methodProxy, callParameters.Cast <CodeExpression>().ToArray()); if (idlMethod.Return != null) // If got return type { // TODO - return values. // Add invocation of actual interface method and store result. CodeVariableDeclarationStatement exprResult = new CodeVariableDeclarationStatement(typerefResult, resultName, invokeProxy); methodCall.Statements.Add(exprResult); // Initialise result parameter in Result struct. callResultArgs.Insert(0, new CodeArgumentReferenceExpression(resultName)); } // Ends if got return type else // Else no return type { // Add invocation of actual interface method and ignore result. methodCall.Statements.Add(invokeProxy); } // Ends else no return type if (typerefResults != null) // If got result type { // Create Call return statement. CodeMethodReturnStatement retCall = new CodeMethodReturnStatement( new CodeObjectCreateExpression(typerefResults, callResultArgs.Cast <CodeExpression>().ToArray()) ); methodCall.Statements.Add(retCall); } // Ends if got result type // Add call method to type. typeProxy.Members.Add(methodCall); // Add async method implementation... if (exprAsyncParamValue == null) // If no params { // Just pass the proxy. exprAsyncParamValue = thisProxyFieldRef; } // Ends if no params methodAsync.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(thisRaiser, asyncMethodName) , new CodeArgumentReferenceExpression("userState") , exprAsyncParamValue , new CodeMethodReferenceExpression(null, methodCall.Name) , new CodeMethodReferenceExpression(null, methodMakeEventArgs.Name) )); methodInterface.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(thisProxyFieldRef, idlMethod.Name) , interfaceCallArgs.Cast <CodeExpression>().ToArray() )); // Finish up. typeEvent.Members.Add(constructorEventArgs); constructorEventArgs.Attributes = MemberAttributes.Public; ns.Types.Add(typeEvent); typeProxy.Members.Add(methodAsync); typeProxy.Members.Add(methodInterface); } // Ends loop over methods } // Ends if got methods }
private void GenerateEntityQueryMethod(DomainOperationEntry domainOperationEntry) { string queryMethodName = domainOperationEntry.Name + QuerySuffix; Type entityType = TypeUtility.GetElementType(domainOperationEntry.ReturnType); CodeMemberMethod queryMethod = new CodeMemberMethod(); queryMethod.Name = queryMethodName; queryMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; // Final needed, else becomes virtual queryMethod.ReturnType = CodeGenUtilities.GetTypeReference(TypeConstants.EntityQueryTypeFullName, this._domainServiceDescription.DomainServiceType.Namespace, false); queryMethod.ReturnType.TypeArguments.Add(CodeGenUtilities.GetTypeReference(entityType.FullName, this._domainServiceDescription.DomainServiceType.Namespace, true)); DomainOperationParameter[] domainOperationEntryParameters = domainOperationEntry.Parameters.ToArray(); // Generate <summary> doc comment string comment = string.Format(CultureInfo.CurrentCulture, Resource.EntityCodeGen_ConstructorComments_Summary_DomainContext, entityType.Name, domainOperationEntry.Name); queryMethod.Comments.AddRange(CodeGenUtilities.GenerateSummaryCodeComment(comment, this.ClientProxyGenerator.IsCSharp)); // Generate <param> doc comments foreach (DomainOperationParameter paramInfo in domainOperationEntryParameters) { comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Query_Method_Parameter_Comment, paramInfo.Name); queryMethod.Comments.AddRange(CodeGenUtilities.GenerateParamCodeComment(paramInfo.Name, comment, this.ClientProxyGenerator.IsCSharp)); } // Generate <returns> doc comments comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Query_Method_Returns_Comment, domainOperationEntry.AssociatedType.Name); queryMethod.Comments.AddRange(CodeGenUtilities.GenerateReturnsCodeComment(comment, this.ClientProxyGenerator.IsCSharp)); // Propagate custom validation attributes 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, queryMethod.Name, this._proxyClass.Name, ex.InnerException.Message), methodAttributes, queryMethod.CustomAttributes, queryMethod.Comments); // add any domain operation entry parameters first CodeVariableReferenceExpression paramsRef = new CodeVariableReferenceExpression("parameters"); if (domainOperationEntryParameters.Length > 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])); queryMethod.Statements.Add(paramsDef); } foreach (DomainOperationParameter paramInfo in domainOperationEntryParameters) { CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression( CodeGenUtilities.GetTypeReference( CodeGenUtilities.TranslateType(paramInfo.ParameterType), this.ClientProxyGenerator, this._proxyClass), paramInfo.Name); // Propagate parameter level validation attributes 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, queryMethod.Name, this._proxyClass.Name, ex.InnerException.Message), paramAttributes, paramDecl.CustomAttributes, queryMethod.Comments, commentHeader); // add the parameter to the query method queryMethod.Parameters.Add(paramDecl); // add the parameter and value to the params dictionary queryMethod.Statements.Add(new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(paramsRef, "Add"), new CodePrimitiveExpression(paramInfo.Name), new CodeVariableReferenceExpression(paramInfo.Name))); } // add argument for queryName CodeExpressionCollection arguments = new CodeExpressionCollection(); arguments.Add(new CodePrimitiveExpression(domainOperationEntry.Name)); // add argument for parameters if (domainOperationEntryParameters.Length > 0) { arguments.Add(paramsRef); } else { arguments.Add(new CodePrimitiveExpression(null)); } // add argument for hasSideEffects QueryAttribute queryAttribute = (QueryAttribute)domainOperationEntry.OperationAttribute; arguments.Add(new CodePrimitiveExpression(queryAttribute.HasSideEffects)); // add argument for isComposable arguments.Add(new CodePrimitiveExpression(queryAttribute.IsComposable)); // this.ValidateMethod("methodName", parameters); CodeExpression paramsExpr = new CodePrimitiveExpression(null); if (domainOperationEntryParameters.Length > 0) { paramsExpr = paramsRef; } CodeExpressionStatement validateMethodCall = new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "ValidateMethod", new CodeExpression[] { new CodePrimitiveExpression(queryMethodName), paramsExpr })); queryMethod.Statements.Add(validateMethodCall); // ---------------------------------------------------------------- // method call: base.CreateQuery(arguments...) // ---------------------------------------------------------------- CodeTypeReference entityTypeRef = CodeGenUtilities.GetTypeReference(entityType.FullName, this._domainServiceDescription.DomainServiceType.Namespace, true); CodeMethodReferenceExpression createQueryMethod = new CodeMethodReferenceExpression(new CodeBaseReferenceExpression(), "CreateQuery", entityTypeRef); CodeMethodReturnStatement createQueryCall = new CodeMethodReturnStatement(new CodeMethodInvokeExpression(createQueryMethod, arguments.Cast <CodeExpression>().ToArray())); queryMethod.Statements.Add(createQueryCall); this._proxyClass.Members.Add(queryMethod); }