ClientClassGenerator.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Description / ClientClassGenerator.cs / 1 / ClientClassGenerator.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Description 
{
    using System; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Configuration;
    using System.CodeDom;
    using System.CodeDom.Compiler; 
    using System.Xml;
    using System.Text; 
    using System.Globalization; 
    using System.Reflection;
    using System.ServiceModel.Configuration; 
    using System.Diagnostics;
    using System.Net.Security;
    using System.Xml.Serialization;
    using System.ComponentModel; 
    using System.Threading;
 
    class ClientClassGenerator : IServiceContractGenerationExtension 
    {
        bool tryAddHelperMethod = false; 
        bool generateEventAsyncMethods = false;

        internal ClientClassGenerator(bool tryAddHelperMethod)
            : this(tryAddHelperMethod, false) 
        {
        } 
 
        internal ClientClassGenerator(bool tryAddHelperMethod, bool generateEventAsyncMethods)
        { 
            this.tryAddHelperMethod = tryAddHelperMethod;
            this.generateEventAsyncMethods = generateEventAsyncMethods;
        }
 
        static Type clientBaseType = typeof(ClientBase<>);
        static Type duplexClientBaseType = typeof(DuplexClientBase<>); 
        static Type instanceContextType = typeof(InstanceContext); 
        static Type objectType = typeof(object);
        static Type objectArrayType = typeof(object[]); 
        static Type exceptionType = typeof(Exception);
        static Type boolType = typeof(bool);
        static Type stringType = typeof(string);
        static Type endpointAddressType = typeof(EndpointAddress); 
        static Type uriType = typeof(Uri);
        static Type bindingType = typeof(Binding); 
        static Type sendOrPostCallbackType = typeof(SendOrPostCallback); 
        static Type asyncCompletedEventArgsType = typeof(AsyncCompletedEventArgs);
        static Type eventHandlerType = typeof(EventHandler<>); 
        static Type voidType = typeof(void);
        static Type asyncResultType = typeof(IAsyncResult);
        static Type asyncCallbackType = typeof(AsyncCallback);
 
        static CodeTypeReference voidTypeRef = new CodeTypeReference(typeof(void));
        static CodeTypeReference asyncResultTypeRef = new CodeTypeReference(typeof(IAsyncResult)); 
 
        static string inputInstanceName = "callbackInstance";
        static string invokeAsyncCompletedEventArgsTypeName = "InvokeAsyncCompletedEventArgs"; 
        static string invokeAsyncMethodName = "InvokeAsync";
        static string raiseExceptionIfNecessaryMethodName = "RaiseExceptionIfNecessary";
        static string beginOperationDelegateTypeName = "BeginOperationDelegate";
        static string endOperationDelegateTypeName = "EndOperationDelegate"; 
        static string getDefaultValueForInitializationMethodName = "GetDefaultValueForInitialization";
 
        // IMPORTANT: this table tracks the set of .ctors in ClientBase and DuplexClientBase. 
        // This table must be kept in sync
        // for DuplexClientBase, the initial InstanceContext param is assumed; ctor overloads must match between ClientBase and DuplexClientBase 
        static Type[][] ClientCtorParamTypes = new Type[][]
            {
                new Type[] { },
                new Type[] { stringType, }, 
                new Type[] { stringType, stringType, },
                new Type[] { stringType, endpointAddressType, }, 
                new Type[] { bindingType, endpointAddressType, }, 
            };
 
        static string[][] ClientCtorParamNames = new string[][]
            {
                new string[] { },
                new string[] { "endpointConfigurationName", }, 
                new string[] { "endpointConfigurationName", "remoteAddress", },
                new string[] { "endpointConfigurationName", "remoteAddress", }, 
                new string[] { "binding", "remoteAddress", }, 
            };
 
        static Type[] EventArgsCtorParamTypes = new Type[]
        {
            objectArrayType,
            exceptionType, 
            boolType,
            objectType 
        }; 

        static string[] EventArgsCtorParamNames = new string[] 
        {
            "results",
            "exception",
            "cancelled", 
            "userState"
        }; 
 
        static string[] EventArgsPropertyNames = new string[]
        { 
            "Results",
            "Error",
            "Cancelled",
            "UserState" 
        };
 
#if DEBUG 
        static BindingFlags ctorBindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
        static string DebugCheckTable_errorString = "Client code generation table out of sync with ClientBase and DuplexClientBase ctors. Please investigate."; 

        // check the table against what we would get from reflection
        static void DebugCheckTable()
        { 
            DiagnosticUtility.DebugAssert(ClientCtorParamNames.Length == ClientCtorParamTypes.Length, DebugCheckTable_errorString);
 
            for (int i = 0; i < ClientCtorParamTypes.Length; i++) 
            {
                DebugCheckTable_ValidateCtor(clientBaseType.GetConstructor(ctorBindingFlags, null, ClientCtorParamTypes[i], null), ClientCtorParamNames[i]); 

                Type[] duplexCtorTypes1 = DebugCheckTable_InsertAtStart(ClientCtorParamTypes[i], objectType);
                Type[] duplexCtorTypes2 = DebugCheckTable_InsertAtStart(ClientCtorParamTypes[i], instanceContextType);
                string[] duplexCtorNames = DebugCheckTable_InsertAtStart(ClientCtorParamNames[i], inputInstanceName); 

                DebugCheckTable_ValidateCtor(duplexClientBaseType.GetConstructor(ctorBindingFlags, null, duplexCtorTypes1, null), duplexCtorNames); 
                DebugCheckTable_ValidateCtor(duplexClientBaseType.GetConstructor(ctorBindingFlags, null, duplexCtorTypes2, null), duplexCtorNames); 
            }
 
            // ClientBase<> has extra InstanceContext overloads that we do not call directly from the generated code, but which we
            // need to account for in this assert
            DiagnosticUtility.DebugAssert(clientBaseType.GetConstructors(ctorBindingFlags).Length == ClientCtorParamTypes.Length * 2, DebugCheckTable_errorString);
 
            // DuplexClientBase<> also has extra object/InstanceContext overloads (but we call these)
            DiagnosticUtility.DebugAssert(duplexClientBaseType.GetConstructors(ctorBindingFlags).Length == ClientCtorParamTypes.Length * 2, DebugCheckTable_errorString); 
        } 

        static T[] DebugCheckTable_InsertAtStart(T[] arr, T item) 
        {
            T[] newArr = new T[arr.Length + 1];
            newArr[0] = item;
            Array.Copy(arr, 0, newArr, 1, arr.Length); 
            return newArr;
        } 
 
        static void DebugCheckTable_ValidateCtor(ConstructorInfo ctor, string[] paramNames)
        { 
            DiagnosticUtility.DebugAssert(ctor != null, DebugCheckTable_errorString);

            ParameterInfo[] parameters = ctor.GetParameters();
            DiagnosticUtility.DebugAssert(parameters.Length == paramNames.Length, DebugCheckTable_errorString); 
            for (int i = 0; i < paramNames.Length; i++)
            { 
                DiagnosticUtility.DebugAssert(parameters[i].Name == paramNames[i], DebugCheckTable_errorString); 
            }
        } 
#endif

        void IServiceContractGenerationExtension.GenerateContract(ServiceContractGenerationContext context)
        { 
#if DEBUG
            DebugCheckTable(); 
#endif 
            CodeTypeDeclaration clientType = context.TypeFactory.CreateClassType();
            // Have to make sure that client name does not match any methods: member names can not be the same as their enclosing type (CSharp only) 
            clientType.Name = NamingHelper.GetUniqueName(GetClientClassName(context.ContractType.Name), DoesMethodNameExist, context.Operations);
            CodeTypeReference contractTypeRef = context.ContractTypeReference;
            if (context.DuplexCallbackType == null)
                clientType.BaseTypes.Add(new CodeTypeReference(context.ServiceContractGenerator.GetCodeTypeReference(typeof(ClientBase<>)).BaseType, context.ContractTypeReference)); 
            else
                clientType.BaseTypes.Add(new CodeTypeReference(context.ServiceContractGenerator.GetCodeTypeReference(typeof(DuplexClientBase<>)).BaseType, context.ContractTypeReference)); 
 
            clientType.BaseTypes.Add(context.ContractTypeReference);
 
            if (!(ClientCtorParamNames.Length == ClientCtorParamTypes.Length))
            {
                DiagnosticUtility.DebugAssert("Invalid client generation constructor table initialization");
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid client generation constructor table initialization"))); 
            }
 
            for (int i = 0; i < ClientCtorParamNames.Length; i++) 
            {
                if (!(ClientCtorParamNames[i].Length == ClientCtorParamTypes[i].Length)) 
                {
                    DiagnosticUtility.DebugAssert("Invalid client generation constructor table initialization");
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid client generation constructor table initialization")));
                } 

                CodeConstructor ctor = new CodeConstructor(); 
                ctor.Attributes = MemberAttributes.Public; 
                if (context.DuplexCallbackType != null)
                { 
                    ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(InstanceContext), inputInstanceName));
                    ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(inputInstanceName));
                }
                for (int j = 0; j < ClientCtorParamNames[i].Length; j++) 
                {
                    ctor.Parameters.Add(new CodeParameterDeclarationExpression(ClientCtorParamTypes[i][j], ClientCtorParamNames[i][j])); 
                    ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(ClientCtorParamNames[i][j])); 
                }
                clientType.Members.Add(ctor); 
            }

            foreach (OperationContractGenerationContext operationContext in context.Operations)
            { 
                // Note that we generate all the client-side methods, even inherited ones.
                if (operationContext.Operation.IsServerInitiated()) continue; 
                CodeTypeReference declaringContractTypeRef = operationContext.DeclaringTypeReference; 
                GenerateClientClassMethod(clientType, contractTypeRef, operationContext.SyncMethod, this.tryAddHelperMethod, declaringContractTypeRef);
 
                if (operationContext.IsAsync)
                {
                    CodeMemberMethod beginMethod = GenerateClientClassMethod(clientType, contractTypeRef, operationContext.BeginMethod, this.tryAddHelperMethod, declaringContractTypeRef);
                    CodeMemberMethod endMethod = GenerateClientClassMethod(clientType, contractTypeRef, operationContext.EndMethod, this.tryAddHelperMethod, declaringContractTypeRef); 

                    if (this.generateEventAsyncMethods) 
                    { 
                        GenerateEventAsyncMethods(context, clientType, operationContext.SyncMethod.Name, beginMethod, endMethod);
                    } 
                }
            }

            context.Namespace.Types.Add(clientType); 
            context.ClientType = clientType;
            context.ClientTypeReference = ServiceContractGenerator.NamespaceHelper.GetCodeTypeReference(context.Namespace, clientType); 
        } 

        static CodeMemberMethod GenerateClientClassMethod(CodeTypeDeclaration clientType, CodeTypeReference contractTypeRef, CodeMemberMethod method, bool addHelperMethod, CodeTypeReference declaringContractTypeRef) 
        {
            CodeMemberMethod methodImpl = GetImplementationOfMethod(contractTypeRef, method);
            AddMethodImpl(methodImpl);
            int methodPosition = clientType.Members.Add(methodImpl); 
            CodeMemberMethod helperMethod = null;
 
            if (addHelperMethod) 
            {
                helperMethod = GenerateHelperMethod(declaringContractTypeRef, methodImpl); 
                if (helperMethod != null)
                {
                    clientType.Members[methodPosition].CustomAttributes.Add(CreateEditorBrowsableAttribute(EditorBrowsableState.Advanced));
                    clientType.Members.Add(helperMethod); 
                }
            } 
 
            return (helperMethod != null) ? helperMethod : methodImpl;
        } 

        static CodeAttributeDeclaration CreateEditorBrowsableAttribute(EditorBrowsableState editorBrowsableState)
        {
            CodeAttributeDeclaration browsableAttribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(EditorBrowsableAttribute))); 
            CodeTypeReferenceExpression browsableAttributeState = new CodeTypeReferenceExpression(typeof(EditorBrowsableState));
            CodeAttributeArgument browsableAttributeValue = new CodeAttributeArgument(new CodeFieldReferenceExpression(browsableAttributeState, editorBrowsableState.ToString())); 
            browsableAttribute.Arguments.Add(browsableAttributeValue); 

            return browsableAttribute; 
        }

        private static CodeMemberMethod GenerateHelperMethod(CodeTypeReference ifaceType, CodeMemberMethod method)
        { 
            CodeMemberMethod helperMethod = new CodeMemberMethod();
            helperMethod.Name = method.Name; 
            helperMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; 
            CodeMethodInvokeExpression invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeCastExpression(ifaceType, new CodeThisReferenceExpression()), method.Name));
            bool hasTypedMessage = false; 
            foreach (CodeParameterDeclarationExpression param in method.Parameters)
            {
                CodeTypeDeclaration paramTypeDecl = ServiceContractGenerator.NamespaceHelper.GetCodeType(param.Type);
                if (paramTypeDecl != null) 
                {
                    hasTypedMessage = true; 
                    CodeVariableReferenceExpression inValue = new CodeVariableReferenceExpression("inValue"); 
                    helperMethod.Statements.Add(new CodeVariableDeclarationStatement(param.Type, inValue.VariableName, new CodeObjectCreateExpression(param.Type)));
                    invokeMethod.Parameters.Add(inValue); 
                    GenerateParameters(helperMethod, paramTypeDecl, inValue, FieldDirection.In);
                }
                else
                { 
                    helperMethod.Parameters.Add(new CodeParameterDeclarationExpression(param.Type, param.Name));
                    invokeMethod.Parameters.Add(new CodeArgumentReferenceExpression(param.Name)); 
                } 
            }
            if (method.ReturnType.BaseType == voidTypeRef.BaseType) 
                helperMethod.Statements.Add(invokeMethod);
            else
            {
                CodeTypeDeclaration returnTypeDecl = ServiceContractGenerator.NamespaceHelper.GetCodeType(method.ReturnType); 
                if (returnTypeDecl != null)
                { 
                    hasTypedMessage = true; 
                    CodeVariableReferenceExpression outVar = new CodeVariableReferenceExpression("retVal");
 
                    helperMethod.Statements.Add(new CodeVariableDeclarationStatement(method.ReturnType, outVar.VariableName, invokeMethod));
                    CodeMethodReturnStatement returnStatement = GenerateParameters(helperMethod, returnTypeDecl, outVar, FieldDirection.Out);
                    if (returnStatement != null)
                        helperMethod.Statements.Add(returnStatement); 
                }
                else 
                { 
                    helperMethod.Statements.Add(new CodeMethodReturnStatement(invokeMethod));
                    helperMethod.ReturnType = method.ReturnType; 
                }
            }
            if (hasTypedMessage)
                method.PrivateImplementationType = ifaceType; 
            return hasTypedMessage ? helperMethod : null;
        } 
 
        private static CodeMethodReturnStatement GenerateParameters(CodeMemberMethod helperMethod, CodeTypeDeclaration codeTypeDeclaration, CodeExpression target, FieldDirection dir)
        { 
            CodeMethodReturnStatement returnStatement = null;
            foreach (CodeTypeMember member in codeTypeDeclaration.Members)
            {
                CodeMemberField field = member as CodeMemberField; 
                if (field == null)
                    continue; 
                CodeFieldReferenceExpression fieldRef = new CodeFieldReferenceExpression(target, field.Name); 
                CodeTypeDeclaration bodyTypeDecl = ServiceContractGenerator.NamespaceHelper.GetCodeType(field.Type);
                if (bodyTypeDecl != null) 
                {
                    if (dir == FieldDirection.In)
                        helperMethod.Statements.Add(new CodeAssignStatement(fieldRef, new CodeObjectCreateExpression(field.Type)));
                    returnStatement = GenerateParameters(helperMethod, bodyTypeDecl, fieldRef, dir); 
                    continue;
                } 
                CodeParameterDeclarationExpression param = GetRefParameter(helperMethod.Parameters, dir, field); 
                if (param == null && dir == FieldDirection.Out && helperMethod.ReturnType.BaseType == voidTypeRef.BaseType)
                { 
                    helperMethod.ReturnType = field.Type;
                    returnStatement = new CodeMethodReturnStatement(fieldRef);
                }
                else 
                {
                    if (param == null) 
                    { 
                        param = new CodeParameterDeclarationExpression(field.Type, NamingHelper.GetUniqueName(field.Name, DoesParameterNameExist, helperMethod));
                        param.Direction = dir; 
                        helperMethod.Parameters.Add(param);
                    }
                    if (dir == FieldDirection.Out)
                        helperMethod.Statements.Add(new CodeAssignStatement(new CodeArgumentReferenceExpression(param.Name), fieldRef)); 
                    else
                        helperMethod.Statements.Add(new CodeAssignStatement(fieldRef, new CodeArgumentReferenceExpression(param.Name))); 
                } 
            }
            return returnStatement; 
        }

        private static CodeParameterDeclarationExpression GetRefParameter(CodeParameterDeclarationExpressionCollection parameters, FieldDirection dir, CodeMemberField field)
        { 
            foreach (CodeParameterDeclarationExpression p in parameters)
            { 
                if (p.Name == field.Name) 
                {
                    if (p.Direction != dir && p.Type.BaseType == field.Type.BaseType) 
                    {
                        p.Direction = FieldDirection.Ref;
                        return p;
                    } 
                    return null;
                } 
            } 
            return null;
        } 

        internal static bool DoesMemberNameExist(string name, object typeDeclarationObject)
        {
            CodeTypeDeclaration typeDeclaration = (CodeTypeDeclaration)typeDeclarationObject; 

            if (string.Compare(typeDeclaration.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
            { 
                return true;
            } 

            foreach (CodeTypeMember member in typeDeclaration.Members)
            {
                if (string.Compare(member.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
                {
                    return true; 
                } 
            }
 
            return false;
        }

        internal static bool DoesTypeNameExists(string name, object codeTypeDeclarationCollectionObject) 
        {
            CodeTypeDeclarationCollection codeTypeDeclarations = (CodeTypeDeclarationCollection)codeTypeDeclarationCollectionObject; 
            foreach (CodeTypeDeclaration codeTypeDeclaration in codeTypeDeclarations) 
            {
                if (string.Compare(codeTypeDeclaration.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
                {
                    return true;
                }
            } 

            return false; 
        } 

        internal static bool DoesTypeAndMemberNameExist(string name, object nameCollection) 
        {
            object[] nameCollections = (object[])nameCollection;

            if (DoesTypeNameExists(name, nameCollections[0])) 
            {
                return true; 
            } 
            if (DoesMemberNameExist(name, nameCollections[1]))
            { 
                return true;
            }

            return false; 
        }
 
        internal static bool DoesMethodNameExist(string name, object operationsObject) 
        {
            Collection operations = (Collection)operationsObject; 
            foreach (OperationContractGenerationContext operationContext in operations)
            {
                if (String.Compare(operationContext.SyncMethod.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
                    return true; 
                if (operationContext.IsAsync)
                { 
                    if (String.Compare(operationContext.BeginMethod.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
                        return true;
                    if (String.Compare(operationContext.EndMethod.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
                        return true;
                }
            }
            return false; 
        }
 
        internal static bool DoesParameterNameExist(string name, object methodObject) 
        {
            CodeMemberMethod method = (CodeMemberMethod)methodObject; 
            if (String.Compare(method.Name, name, StringComparison.OrdinalIgnoreCase) == 0)
                return true;
            CodeParameterDeclarationExpressionCollection parameters = method.Parameters;
            foreach (CodeParameterDeclarationExpression p in parameters) 
            {
                if (String.Compare(p.Name, name, StringComparison.OrdinalIgnoreCase) == 0) 
                    return true; 
            }
            return false; 
        }

        static void AddMethodImpl(CodeMemberMethod method)
        { 
            CodeMethodInvokeExpression methodInvoke = new CodeMethodInvokeExpression(GetChannelReference(), method.Name);
            foreach (CodeParameterDeclarationExpression parameter in method.Parameters) 
            { 
                methodInvoke.Parameters.Add(new CodeDirectionExpression(parameter.Direction, new CodeVariableReferenceExpression(parameter.Name)));
            } 
            if (IsVoid(method))
                method.Statements.Add(methodInvoke);
            else
                method.Statements.Add(new CodeMethodReturnStatement(methodInvoke)); 
        }
 
        static CodeMemberMethod GetImplementationOfMethod(CodeTypeReference ifaceType, CodeMemberMethod method) 
        {
            CodeMemberMethod m = new CodeMemberMethod(); 
            m.Name = method.Name;
            m.ImplementationTypes.Add(ifaceType);
            m.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            foreach (CodeParameterDeclarationExpression parameter in method.Parameters) 
            {
                CodeParameterDeclarationExpression newParam = new CodeParameterDeclarationExpression(parameter.Type, parameter.Name); 
                newParam.Direction = parameter.Direction; 
                m.Parameters.Add(newParam);
            } 
            m.ReturnType = method.ReturnType;
            return m;
        }
 
        static void GenerateEventAsyncMethods(ServiceContractGenerationContext context, CodeTypeDeclaration clientType,
            string syncMethodName, CodeMemberMethod beginMethod, CodeMemberMethod endMethod) 
        { 
            CodeTypeDeclaration operationCompletedEventArgsType = CreateOperationCompletedEventArgsType(context, syncMethodName, endMethod);
            CodeMemberEvent operationCompletedEvent = CreateOperationCompletedEvent(context, clientType, syncMethodName, operationCompletedEventArgsType); 

            CodeMemberField beginOperationDelegate = CreateBeginOperationDelegate(context, clientType, syncMethodName);
            CodeMemberMethod beginOperationMethod = CreateBeginOperationMethod(context, clientType, syncMethodName, beginMethod);
 
            CodeMemberField endOperationDelegate = CreateEndOperationDelegate(context, clientType, syncMethodName);
            CodeMemberMethod endOperationMethod = CreateEndOperationMethod(context, clientType, syncMethodName, endMethod); 
 
            CodeMemberField operationCompletedDelegate = CreateOperationCompletedDelegate(context, clientType, syncMethodName);
            CodeMemberMethod operationCompletedMethod = CreateOperationCompletedMethod(context, clientType, syncMethodName, operationCompletedEventArgsType, operationCompletedEvent); 

            CodeMemberMethod eventAsyncMethod = CreateEventAsyncMethod(context, clientType, syncMethodName, beginMethod,
                beginOperationDelegate, beginOperationMethod, endOperationDelegate, endOperationMethod, operationCompletedDelegate, operationCompletedMethod);
 
            CreateEventAsyncMethodOverload(clientType, eventAsyncMethod);
 
            // hide the normal async methods from intellisense 
            beginMethod.CustomAttributes.Add(CreateEditorBrowsableAttribute(EditorBrowsableState.Advanced));
            endMethod.CustomAttributes.Add(CreateEditorBrowsableAttribute(EditorBrowsableState.Advanced)); 
        }

        static CodeTypeDeclaration CreateOperationCompletedEventArgsType(ServiceContractGenerationContext context,
            string syncMethodName, CodeMemberMethod endMethod) 
        {
            if ((endMethod.Parameters.Count == 1) && (endMethod.ReturnType.BaseType == voidTypeRef.BaseType)) 
            { 
                // no need to create new event args type, use AsyncCompletedEventArgs
                return null; 
            }

            CodeTypeDeclaration argsType = context.TypeFactory.CreateClassType();
            argsType.BaseTypes.Add(new CodeTypeReference(asyncCompletedEventArgsType)); 

            // define object[] results field. 
            CodeMemberField resultsField = new CodeMemberField(); 
            resultsField.Type = new CodeTypeReference(objectArrayType);
 
            CodeFieldReferenceExpression resultsFieldReference = new CodeFieldReferenceExpression();
            resultsFieldReference.TargetObject = new CodeThisReferenceExpression();

            // create constructor, that assigns the results field. 
            CodeConstructor ctor = new CodeConstructor();
            ctor.Attributes = MemberAttributes.Public; 
            for (int i = 0; i < EventArgsCtorParamTypes.Length; i++) 
            {
                ctor.Parameters.Add(new CodeParameterDeclarationExpression(EventArgsCtorParamTypes[i], EventArgsCtorParamNames[i])); 
                if (i > 0)
                {
                    ctor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(EventArgsCtorParamNames[i]));
                } 
            }
            argsType.Members.Add(ctor); 
            ctor.Statements.Add(new CodeAssignStatement(resultsFieldReference, new CodeVariableReferenceExpression(EventArgsCtorParamNames[0]))); 

            // create properties for the out parameters 
            int asyncResultParamIndex = GetAsyncResultParamIndex(endMethod);
            int count = 0;
            for (int i = 0; i < endMethod.Parameters.Count; i++)
            { 
                if (i != asyncResultParamIndex)
                { 
                    CreateEventAsyncCompletedArgsTypeProperty(argsType, 
                        endMethod.Parameters[i].Type,
                        endMethod.Parameters[i].Name, 
                        new CodeArrayIndexerExpression(resultsFieldReference, new CodePrimitiveExpression(count++)));
                }
            }
 
            // create the property for the return type
            if (endMethod.ReturnType.BaseType != voidTypeRef.BaseType) 
            { 
                CreateEventAsyncCompletedArgsTypeProperty(
                    argsType, 
                    endMethod.ReturnType,
                    NamingHelper.GetUniqueName("Result", DoesMemberNameExist, argsType),
                    new CodeArrayIndexerExpression(resultsFieldReference,
                        new CodePrimitiveExpression(count))); 

            } 
 
            // Name the "results" field after generating the properties to make sure it does
            // not conflict with the property names. 
            resultsField.Name = NamingHelper.GetUniqueName("results", DoesMemberNameExist, argsType);
            resultsFieldReference.FieldName = resultsField.Name;
            argsType.Members.Add(resultsField);
 
            // Name the type making sure that it does not conflict with its members and types already present in
            // the namespace. 
            argsType.Name = NamingHelper.GetUniqueName(GetOperationCompletedEventArgsTypeName(syncMethodName), 
                DoesTypeAndMemberNameExist, new object[] { context.Namespace.Types, argsType });
            context.Namespace.Types.Add(argsType); 

            return argsType;
        }
 
        static int GetAsyncResultParamIndex(CodeMemberMethod endMethod)
        { 
            int index = endMethod.Parameters.Count - 1; 
            if (endMethod.Parameters[index].Type.BaseType != asyncResultTypeRef.BaseType)
            { 
                // workaround for CSD Dev Framework:10826, the unwrapped end method has IAsyncResult as first param.
                index = 0;
            }
 
            return index;
        } 
 
        static CodeMemberProperty CreateEventAsyncCompletedArgsTypeProperty(CodeTypeDeclaration ownerTypeDecl,
            CodeTypeReference propertyType, string propertyName, CodeExpression propertyValueExpr) 
        {
            CodeMemberProperty property = new CodeMemberProperty();
            property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            property.Type = propertyType; 
            property.Name = propertyName;
            property.HasSet = false; 
            property.HasGet = true; 

            CodeCastExpression castExpr = new CodeCastExpression(propertyType, propertyValueExpr); 
            CodeMethodReturnStatement returnStmt = new CodeMethodReturnStatement(castExpr);

            property.GetStatements.Add(new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), raiseExceptionIfNecessaryMethodName));
            property.GetStatements.Add(returnStmt); 
            ownerTypeDecl.Members.Add(property);
 
            return property; 
        }
 
        static CodeMemberEvent CreateOperationCompletedEvent(ServiceContractGenerationContext context,
            CodeTypeDeclaration clientType, string syncMethodName, CodeTypeDeclaration operationCompletedEventArgsType)
        {
            CodeMemberEvent operationCompletedEvent = new CodeMemberEvent(); 
            operationCompletedEvent.Attributes = MemberAttributes.Public;
            operationCompletedEvent.Type = new CodeTypeReference(eventHandlerType); 
 
            if (operationCompletedEventArgsType == null)
            { 
                operationCompletedEvent.Type.TypeArguments.Add(asyncCompletedEventArgsType);
            }
            else
            { 
                operationCompletedEvent.Type.TypeArguments.Add(operationCompletedEventArgsType.Name);
            } 
 
            operationCompletedEvent.Name = NamingHelper.GetUniqueName(GetOperationCompletedEventName(syncMethodName),
                DoesMethodNameExist, context.Operations); 

            clientType.Members.Add(operationCompletedEvent);
            return operationCompletedEvent;
        } 

        static CodeMemberField CreateBeginOperationDelegate(ServiceContractGenerationContext context, 
            CodeTypeDeclaration clientType, string syncMethodName) 
        {
            CodeMemberField beginOperationDelegate = new CodeMemberField(); 
            beginOperationDelegate.Attributes = MemberAttributes.Private;
            beginOperationDelegate.Type = new CodeTypeReference(beginOperationDelegateTypeName);
            beginOperationDelegate.Name = NamingHelper.GetUniqueName(GetBeginOperationDelegateName(syncMethodName),
                DoesMethodNameExist, context.Operations); 

            clientType.Members.Add(beginOperationDelegate); 
            return beginOperationDelegate; 
        }
 
        static CodeMemberMethod CreateBeginOperationMethod(ServiceContractGenerationContext context, CodeTypeDeclaration clientType,
            string syncMethodName, CodeMemberMethod beginMethod)
        {
            CodeMemberMethod onBeginOperationMethod = new CodeMemberMethod(); 
            onBeginOperationMethod.Attributes = MemberAttributes.Private;
            onBeginOperationMethod.ReturnType = new CodeTypeReference(asyncResultType); 
            onBeginOperationMethod.Name = NamingHelper.GetUniqueName(GetBeginOperationMethodName(syncMethodName), 
                DoesMethodNameExist, context.Operations);
 
            CodeParameterDeclarationExpression inValuesParam = new CodeParameterDeclarationExpression();
            inValuesParam.Type = new CodeTypeReference(objectArrayType);
            inValuesParam.Name = NamingHelper.GetUniqueName("inValues", DoesParameterNameExist, beginMethod);
            onBeginOperationMethod.Parameters.Add(inValuesParam); 

            CodeMethodInvokeExpression invokeBegin = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), beginMethod.Name); 
            CodeExpression inValuesRef = new CodeVariableReferenceExpression(inValuesParam.Name); 

            for (int i = 0; i < beginMethod.Parameters.Count - 2; i++) 
            {
                CodeVariableDeclarationStatement variableDecl = new CodeVariableDeclarationStatement();
                variableDecl.Type = beginMethod.Parameters[i].Type;
                variableDecl.Name = beginMethod.Parameters[i].Name; 
                variableDecl.InitExpression = new CodeCastExpression(variableDecl.Type,
                    new CodeArrayIndexerExpression(inValuesRef, new CodePrimitiveExpression(i))); 
 
                onBeginOperationMethod.Statements.Add(variableDecl);
                invokeBegin.Parameters.Add(new CodeDirectionExpression(beginMethod.Parameters[i].Direction, 
                    new CodeVariableReferenceExpression(variableDecl.Name)));
            }

            for (int i = beginMethod.Parameters.Count - 2; i < beginMethod.Parameters.Count; i++) 
            {
                onBeginOperationMethod.Parameters.Add(new CodeParameterDeclarationExpression( 
                    beginMethod.Parameters[i].Type, beginMethod.Parameters[i].Name)); 
                invokeBegin.Parameters.Add(new CodeVariableReferenceExpression(beginMethod.Parameters[i].Name));
            } 

            onBeginOperationMethod.Statements.Add(new CodeMethodReturnStatement(invokeBegin));
            clientType.Members.Add(onBeginOperationMethod);
            return onBeginOperationMethod; 
        }
 
        static CodeMemberField CreateEndOperationDelegate(ServiceContractGenerationContext context, 
            CodeTypeDeclaration clientType, string syncMethodName)
        { 
            CodeMemberField endOperationDelegate = new CodeMemberField();
            endOperationDelegate.Attributes = MemberAttributes.Private;
            endOperationDelegate.Type = new CodeTypeReference(endOperationDelegateTypeName);
            endOperationDelegate.Name = NamingHelper.GetUniqueName(GetEndOperationDelegateName(syncMethodName), 
                DoesMethodNameExist, context.Operations);
 
            clientType.Members.Add(endOperationDelegate); 
            return endOperationDelegate;
        } 

        static CodeMemberMethod CreateEndOperationMethod(ServiceContractGenerationContext context, CodeTypeDeclaration clientType, string syncMethodName, CodeMemberMethod endMethod)
        {
            CodeMemberMethod onEndOperationMethod = new CodeMemberMethod(); 
            onEndOperationMethod.Attributes = MemberAttributes.Private;
            onEndOperationMethod.ReturnType = new CodeTypeReference(objectArrayType); 
            onEndOperationMethod.Name = NamingHelper.GetUniqueName(GetEndOperationMethodName(syncMethodName), DoesMethodNameExist, context.Operations); 

            int asyncResultParamIndex = GetAsyncResultParamIndex(endMethod); 
            CodeMethodInvokeExpression invokeEnd = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), endMethod.Name);
            CodeArrayCreateExpression retArray = new CodeArrayCreateExpression();
            retArray.CreateType = new CodeTypeReference(objectArrayType);
            for (int i = 0; i < endMethod.Parameters.Count; i++) 
            {
                if (i == asyncResultParamIndex) 
                { 
                    onEndOperationMethod.Parameters.Add(new CodeParameterDeclarationExpression(
                        endMethod.Parameters[i].Type, endMethod.Parameters[i].Name)); 
                    invokeEnd.Parameters.Add(new CodeVariableReferenceExpression(endMethod.Parameters[i].Name));
                }
                else
                { 
                    CodeVariableDeclarationStatement variableDecl = new CodeVariableDeclarationStatement(
                        endMethod.Parameters[i].Type, endMethod.Parameters[i].Name); 
                    CodeMethodReferenceExpression getDefaultValueMethodRef = new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), getDefaultValueForInitializationMethodName, endMethod.Parameters[i].Type); 
                    variableDecl.InitExpression = new CodeMethodInvokeExpression(getDefaultValueMethodRef);
                    onEndOperationMethod.Statements.Add(variableDecl); 

                    invokeEnd.Parameters.Add(new CodeDirectionExpression(endMethod.Parameters[i].Direction,
                            new CodeVariableReferenceExpression(variableDecl.Name)));
 
                    retArray.Initializers.Add(new CodeVariableReferenceExpression(variableDecl.Name));
                } 
            } 

            if (endMethod.ReturnType.BaseType != voidTypeRef.BaseType) 
            {
                CodeVariableDeclarationStatement retValDecl = new CodeVariableDeclarationStatement();
                retValDecl.Type = endMethod.ReturnType;
                retValDecl.Name = NamingHelper.GetUniqueName("retVal", DoesParameterNameExist, endMethod); 
                retValDecl.InitExpression = invokeEnd;
                retArray.Initializers.Add(new CodeVariableReferenceExpression(retValDecl.Name)); 
 
                onEndOperationMethod.Statements.Add(retValDecl);
            } 
            else
            {
                onEndOperationMethod.Statements.Add(invokeEnd);
            } 

            if (retArray.Initializers.Count > 0) 
            { 
                onEndOperationMethod.Statements.Add(new CodeMethodReturnStatement(retArray));
            } 
            else
            {
                onEndOperationMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
            } 

            clientType.Members.Add(onEndOperationMethod); 
            return onEndOperationMethod; 
        }
 
        static CodeMemberField CreateOperationCompletedDelegate(ServiceContractGenerationContext context,
            CodeTypeDeclaration clientType, string syncMethodName)
        {
            CodeMemberField operationCompletedDelegate = new CodeMemberField(); 
            operationCompletedDelegate.Attributes = MemberAttributes.Private;
            operationCompletedDelegate.Type = new CodeTypeReference(sendOrPostCallbackType); 
            operationCompletedDelegate.Name = NamingHelper.GetUniqueName(GetOperationCompletedDelegateName(syncMethodName), 
                DoesMethodNameExist, context.Operations);
 
            clientType.Members.Add(operationCompletedDelegate);
            return operationCompletedDelegate;
        }
 
        static CodeMemberMethod CreateOperationCompletedMethod(ServiceContractGenerationContext context, CodeTypeDeclaration clientType,
            string syncMethodName, CodeTypeDeclaration operationCompletedEventArgsType, CodeMemberEvent operationCompletedEvent) 
        { 
            CodeMemberMethod operationCompletedMethod = new CodeMemberMethod();
            operationCompletedMethod.Attributes = MemberAttributes.Private; 
            operationCompletedMethod.Name = NamingHelper.GetUniqueName(GetOperationCompletedMethodName(syncMethodName),
                DoesMethodNameExist, context.Operations);

            operationCompletedMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(objectType), "state")); 
            operationCompletedMethod.ReturnType = new CodeTypeReference(voidType);
 
            CodeVariableDeclarationStatement eventArgsDecl = 
                new CodeVariableDeclarationStatement(invokeAsyncCompletedEventArgsTypeName, "e");
 
            eventArgsDecl.InitExpression = new CodeCastExpression(invokeAsyncCompletedEventArgsTypeName,
                new CodeArgumentReferenceExpression(operationCompletedMethod.Parameters[0].Name));

            CodeObjectCreateExpression newEventArgsExpr; 
            CodeVariableReferenceExpression eventArgsRef = new CodeVariableReferenceExpression(eventArgsDecl.Name);
            if (operationCompletedEventArgsType != null) 
            { 
                newEventArgsExpr = new CodeObjectCreateExpression(operationCompletedEventArgsType.Name,
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[0]), 
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[1]),
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[2]),
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[3]));
            } 
            else
            { 
                newEventArgsExpr = new CodeObjectCreateExpression(asyncCompletedEventArgsType, 
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[1]),
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[2]), 
                    new CodePropertyReferenceExpression(eventArgsRef, EventArgsPropertyNames[3]));
            }

            CodeEventReferenceExpression completedEvent = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), operationCompletedEvent.Name); 

            CodeDelegateInvokeExpression raiseEventExpr = new CodeDelegateInvokeExpression( 
                completedEvent, 
                new CodeThisReferenceExpression(),
                newEventArgsExpr); 

            CodeConditionStatement ifEventHandlerNotNullBlock = new CodeConditionStatement(
                new CodeBinaryOperatorExpression(
                    completedEvent, 
                    CodeBinaryOperatorType.IdentityInequality,
                    new CodePrimitiveExpression(null)), 
                eventArgsDecl, 
                new CodeExpressionStatement(raiseEventExpr));
 
            operationCompletedMethod.Statements.Add(ifEventHandlerNotNullBlock);

            clientType.Members.Add(operationCompletedMethod);
            return operationCompletedMethod; 
        }
 
        static CodeMemberMethod CreateEventAsyncMethod(ServiceContractGenerationContext context, CodeTypeDeclaration clientType, 
            string syncMethodName, CodeMemberMethod beginMethod,
            CodeMemberField beginOperationDelegate, CodeMemberMethod beginOperationMethod, 
            CodeMemberField endOperationDelegate, CodeMemberMethod endOperationMethod,
            CodeMemberField operationCompletedDelegate, CodeMemberMethod operationCompletedMethod)
        {
            CodeMemberMethod eventAsyncMethod = new CodeMemberMethod(); 
            eventAsyncMethod.Name = NamingHelper.GetUniqueName(GetEventAsyncMethodName(syncMethodName),
                DoesMethodNameExist, context.Operations); 
            eventAsyncMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; 
            eventAsyncMethod.ReturnType = new CodeTypeReference(voidType);
 
            CodeArrayCreateExpression invokeAsyncInValues = new CodeArrayCreateExpression(new CodeTypeReference(objectArrayType));
            for (int i = 0; i < beginMethod.Parameters.Count - 2; i++)
            {
                CodeParameterDeclarationExpression beginMethodParameter = beginMethod.Parameters[i]; 
                CodeParameterDeclarationExpression eventAsyncMethodParameter = new CodeParameterDeclarationExpression(
                    beginMethodParameter.Type, beginMethodParameter.Name); 
 
                eventAsyncMethodParameter.Direction = FieldDirection.In;
                eventAsyncMethod.Parameters.Add(eventAsyncMethodParameter); 
                invokeAsyncInValues.Initializers.Add(new CodeVariableReferenceExpression(eventAsyncMethodParameter.Name));
            }

            string userStateParamName = NamingHelper.GetUniqueName("userState", DoesParameterNameExist, eventAsyncMethod); 
            eventAsyncMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(objectType), userStateParamName));
 
            eventAsyncMethod.Statements.Add(CreateDelegateIfNotNull(beginOperationDelegate, beginOperationMethod)); 
            eventAsyncMethod.Statements.Add(CreateDelegateIfNotNull(endOperationDelegate, endOperationMethod));
            eventAsyncMethod.Statements.Add(CreateDelegateIfNotNull(operationCompletedDelegate, operationCompletedMethod)); 

            CodeMethodInvokeExpression invokeAsync = new CodeMethodInvokeExpression(new CodeBaseReferenceExpression(), invokeAsyncMethodName);
            invokeAsync.Parameters.Add(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), beginOperationDelegate.Name));
            if (invokeAsyncInValues.Initializers.Count > 0) 
            {
                invokeAsync.Parameters.Add(invokeAsyncInValues); 
            } 
            else
            { 
                invokeAsync.Parameters.Add(new CodePrimitiveExpression(null));
            }
            invokeAsync.Parameters.Add(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), endOperationDelegate.Name));
            invokeAsync.Parameters.Add(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), operationCompletedDelegate.Name)); 
            invokeAsync.Parameters.Add(new CodeVariableReferenceExpression(userStateParamName));
 
            eventAsyncMethod.Statements.Add(new CodeExpressionStatement(invokeAsync)); 

            clientType.Members.Add(eventAsyncMethod); 
            return eventAsyncMethod;
        }

        static CodeMemberMethod CreateEventAsyncMethodOverload(CodeTypeDeclaration clientType, CodeMemberMethod eventAsyncMethod) 
        {
            CodeMemberMethod eventAsyncMethodOverload = new CodeMemberMethod(); 
            eventAsyncMethodOverload.Attributes = eventAsyncMethod.Attributes; 
            eventAsyncMethodOverload.Name = eventAsyncMethod.Name;
            eventAsyncMethodOverload.ReturnType = eventAsyncMethod.ReturnType; 

            CodeMethodInvokeExpression invokeEventAsyncMethod = new CodeMethodInvokeExpression(
                new CodeThisReferenceExpression(), eventAsyncMethod.Name);
 
            for (int i = 0; i < eventAsyncMethod.Parameters.Count - 1; i++)
            { 
                eventAsyncMethodOverload.Parameters.Add(new CodeParameterDeclarationExpression( 
                    eventAsyncMethod.Parameters[i].Type,
                    eventAsyncMethod.Parameters[i].Name)); 

                invokeEventAsyncMethod.Parameters.Add(new CodeVariableReferenceExpression(
                    eventAsyncMethod.Parameters[i].Name));
            } 
            invokeEventAsyncMethod.Parameters.Add(new CodePrimitiveExpression(null));
 
            eventAsyncMethodOverload.Statements.Add(invokeEventAsyncMethod); 

            int eventAsyncMethodPosition = clientType.Members.IndexOf(eventAsyncMethod); 
            DiagnosticUtility.DebugAssert(eventAsyncMethodPosition != -1,
                "The eventAsyncMethod must be added to the clientType before calling CreateEventAsyncMethodOverload");

            clientType.Members.Insert(eventAsyncMethodPosition, eventAsyncMethodOverload); 
            return eventAsyncMethodOverload;
        } 
 
        static CodeStatement CreateDelegateIfNotNull(CodeMemberField delegateField, CodeMemberMethod delegateMethod)
        { 
            return new CodeConditionStatement(
                new CodeBinaryOperatorExpression(
                    new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), delegateField.Name),
                    CodeBinaryOperatorType.IdentityEquality, 
                    new CodePrimitiveExpression(null)),
                new CodeAssignStatement( 
                    new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), delegateField.Name), 
                    new CodeDelegateCreateExpression(delegateField.Type,
                        new CodeThisReferenceExpression(), delegateMethod.Name))); 
        }

        static string GetClassName(string interfaceName)
        { 
            // maybe strip a leading 'I'
            if (interfaceName.Length >= 2 && 
                String.Compare(interfaceName, 0, Strings.InterfaceTypePrefix, 0, Strings.InterfaceTypePrefix.Length, StringComparison.Ordinal) == 0 && 
                Char.IsUpper(interfaceName, 1))
                return interfaceName.Substring(1); 
            else
                return interfaceName;
        }
 
        static string GetEventAsyncMethodName(string syncMethodName)
        { 
            return string.Format(CultureInfo.InvariantCulture, "{0}Async", syncMethodName); 
        }
 
        static string GetBeginOperationDelegateName(string syncMethodName)
        {
            return string.Format(CultureInfo.InvariantCulture, "onBegin{0}Delegate", syncMethodName);
        } 

        static string GetBeginOperationMethodName(string syncMethodName) 
        { 
            return string.Format(CultureInfo.InvariantCulture, "OnBegin{0}", syncMethodName);
        } 

        static string GetEndOperationDelegateName(string syncMethodName)
        {
            return string.Format(CultureInfo.InvariantCulture, "onEnd{0}Delegate", syncMethodName); 
        }
 
        static string GetEndOperationMethodName(string syncMethodName) 
        {
            return string.Format(CultureInfo.InvariantCulture, "OnEnd{0}", syncMethodName); 
        }

        static string GetOperationCompletedDelegateName(string syncMethodName)
        { 
            return string.Format(CultureInfo.InvariantCulture, "on{0}CompletedDelegate", syncMethodName);
        } 
 
        static string GetOperationCompletedMethodName(string syncMethodName)
        { 
            return string.Format(CultureInfo.InvariantCulture, "On{0}Completed", syncMethodName);
        }

        static string GetOperationCompletedEventName(string syncMethodName) 
        {
            return string.Format(CultureInfo.InvariantCulture, "{0}Completed", syncMethodName); 
        } 

        static string GetOperationCompletedEventArgsTypeName(string syncMethodName) 
        {
            return string.Format(CultureInfo.InvariantCulture, "{0}CompletedEventArgs", syncMethodName);
        }
 
        static internal string GetClientClassName(string interfaceName)
        { 
            return GetClassName(interfaceName) + Strings.ClientTypeSuffix; 
        }
 
        static bool IsVoid(CodeMemberMethod method)
        {
            return method.ReturnType == null || String.Compare(method.ReturnType.BaseType, typeof(void).FullName, StringComparison.Ordinal) == 0;
        } 

        static CodeExpression GetChannelReference() 
        { 
            return new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), Strings.ClientBaseChannelProperty);
        } 

        static class Strings
        {
            public const string ClientBaseChannelProperty = "Channel"; 
            public const string ClientTypeSuffix = "Client";
            public const string InterfaceTypePrefix = "I"; 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK