/// <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();
}
Beispiel #7
0
        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);
        }
Beispiel #8
0
        /// <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));
        }
Beispiel #9
0
    }//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()
Beispiel #10
0
        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");
        }
Beispiel #11
0
/// <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();
        }
        }//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 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;
		}
Beispiel #16
0
        private void GenerateInvokeMethodBody(DomainOperationEntry domainOperationEntry, InvokeKind invokeKind)
        {
            string parameterDictionaryString = this.GenerateServiceOpMethodBody(domainOperationEntry, domainOperationEntry.Name);

            this.GenerateInvokeMethodReturn(domainOperationEntry, parameterDictionaryString, invokeKind);
        }
Beispiel #17
0
        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");
                }
            }
        }
Beispiel #18
0
 /// <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>
        /// 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));
        }