ServiceReflector.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 / ServiceReflector.cs / 1 / ServiceReflector.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Description
{ 
    using System.ServiceModel;
    using System.ServiceModel.Channels; 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Collections; 
    using System.Reflection;
    using System.Globalization;
    using System.Xml;
    using System.Text; 

    static internal class NamingHelper 
    { 
        internal const string DefaultNamespace = "http://tempuri.org/";
        internal const string DefaultServiceName = "service"; 
        internal const string MSNamespace = "http://schemas.microsoft.com/2005/07/ServiceModel";

        // simplified rules for appending paths to base URIs. note that this differs from new Uri(baseUri, string)
        // 1) CombineUriStrings("http://foo/bar/z", "baz") ==> "http://foo/bar/z/baz" 
        // 2) CombineUriStrings("http://foo/bar/z/", "baz") ==> "http://foo/bar/z/baz"
        // 3) CombineUriStrings("http://foo/bar/z", "/baz") ==> "http://foo/bar/z/baz" 
        // 4) CombineUriStrings("http://foo/bar/z", "http://baz/q") ==> "http://baz/q" 
        // 5) CombineUriStrings("http://foo/bar/z", "") ==> ""
 
        internal static string CombineUriStrings(string baseUri, string path)
        {
            if (Uri.IsWellFormedUriString(path, UriKind.Absolute) || path == String.Empty)
            { 
                return path;
            } 
            else 
            {
                // combine 
                if (baseUri.EndsWith("/", StringComparison.Ordinal))
                {
                    return baseUri + (path.StartsWith("/", StringComparison.Ordinal) ? path.Substring(1) : path);
                } 
                else
                { 
                    return baseUri + (path.StartsWith("/", StringComparison.Ordinal) ? path : "/" + path); 
                }
            } 
        }

        internal static string TypeName(Type t)
        { 
            if (t.IsGenericType || t.ContainsGenericParameters)
            { 
                Type[] args = t.GetGenericArguments(); 
                int nameEnd = t.Name.IndexOf('`');
                string result = nameEnd > 0 ? t.Name.Substring(0, nameEnd) : t.Name; 
                result += "Of";
                for (int i = 0; i < args.Length; ++i)
                {
                    result = result + "_" + TypeName(args[i]); 
                }
                return result; 
            } 
            else if (t.IsArray)
            { 
                return "ArrayOf" + TypeName(t.GetElementType());
            }
            else
            { 
                return t.Name;
            } 
        } 

        // name, ns could have any combination of nulls 
        internal static XmlQualifiedName GetContractName(Type contractType, string name, string ns)
        {
            XmlName xmlName = new XmlName(name ?? TypeName(contractType));
            // ns can be empty 
            if (ns == null)
            { 
                ns = DefaultNamespace; 
            }
            return new XmlQualifiedName(xmlName.EncodedName, ns); 
        }

        // name could be null
        // logicalMethodName is MethodInfo.Name with Begin removed for async pattern 
        // return encoded version to be used in OperationDescription
        internal static XmlName GetOperationName(string logicalMethodName, string name) 
        { 
            return new XmlName(String.IsNullOrEmpty(name) ? logicalMethodName : name);
        } 

        // name could be null
        // logicalMethodName is MethodInfo.Name with Begin removed for async pattern
        internal static string GetMessageAction(XmlQualifiedName contractName, string opname, string action, bool isResponse) 
        {
            if (action != null) 
            { 
                return action;
            } 

            System.Text.StringBuilder actionBuilder = new System.Text.StringBuilder(64);
            if (String.IsNullOrEmpty(contractName.Namespace))
            { 
                actionBuilder.Append("urn:");
            } 
            else 
            {
                actionBuilder.Append(contractName.Namespace); 
                if (!contractName.Namespace.EndsWith("/", StringComparison.Ordinal))
                {
                    actionBuilder.Append('/');
                } 
            }
            actionBuilder.Append(contractName.Name); 
            actionBuilder.Append('/'); 
            action = isResponse ? opname + "Response" : opname;
 
            return CombineUriStrings(actionBuilder.ToString(), action);
        }

        internal delegate bool DoesNameExist(string name, object nameCollection); 
        internal static string GetUniqueName(string baseName, DoesNameExist doesNameExist, object nameCollection)
        { 
            for (int i = 0; i < Int32.MaxValue; i++) 
            {
                string name = i > 0 ? baseName + i : baseName; 
                if(!doesNameExist(name, nameCollection))
                {
                    return name;
                } 
            }
            DiagnosticUtility.DebugAssert("Too Many Names"); 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot generate unique name for name {0}", baseName))); 
        }
 
        internal static void CheckUriProperty(string ns, string propName)
        {
            Uri uri;
            if (!Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out uri)) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFXUnvalidNamespaceValue, ns, propName));
        } 
 
        internal static void CheckUriParameter(string ns, string paramName)
        { 
            Uri uri;
            if (!Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out uri))
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(paramName, SR.GetString(SR.SFXUnvalidNamespaceParam, ns));
        } 

        // Converts names that contain characters that are not permitted in XML names to valid names. 
        internal static string XmlName(string name) 
        {
            if (string.IsNullOrEmpty(name)) 
                return name;
            if (IsAsciiLocalName(name))
                return name;
            if (IsValidNCName(name)) 
                return name;
            return XmlConvert.EncodeLocalName(name); 
        } 

        // Transforms an XML name into an object name. 
        internal static string CodeName(string name)
        {
            return XmlConvert.DecodeName(name);
        } 

        static bool IsAlpha(char ch) 
        { 
            return (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z');
        } 

        static bool IsDigit(char ch)
        {
            return (ch >= '0' && ch <= '9'); 
        }
 
        static bool IsAsciiLocalName(string localName) 
        {
            DiagnosticUtility.DebugAssert(null != localName, ""); 
            if (!IsAlpha(localName[0]))
                return false;
            for (int i = 1; i < localName.Length; i++)
            { 
                char ch = localName[i];
                if (!IsAlpha(ch) && !IsDigit(ch)) 
                    return false; 
            }
            return true; 
        }

        internal static bool IsValidNCName(string name)
        { 
            try
            { 
                XmlConvert.VerifyNCName(name); 
                return true;
            } 
            catch (XmlException)
            {
                return false;
            } 
        }
    } 
 
    internal class XmlName
    { 
        string decoded;
        string encoded;

        internal XmlName(string name) : this(name, false) 
        {
        } 
 
        internal XmlName(string name, bool isEncoded)
        { 
            if (isEncoded)
            {
                ValidateEncodedName(name, true /*allowNull*/);
                encoded = name; 
            }
            else 
            { 
                decoded = name;
            } 
        }

        internal string EncodedName
        { 
            get
            { 
                if (encoded == null) 
                    encoded = NamingHelper.XmlName(decoded);
                return encoded; 
            }
        }

        internal string DecodedName 
        {
            get 
            { 
                if (decoded == null)
                    decoded = NamingHelper.CodeName(encoded); 
                return decoded;
            }
        }
 
        static void ValidateEncodedName(string name, bool allowNull)
        { 
            if (allowNull && name == null) 
                return;
            try 
            {
                XmlConvert.VerifyNCName(name);
            }
            catch (XmlException e) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(e.Message, "name")); 
            } 
        }
 
        bool IsEmpty { get { return string.IsNullOrEmpty(encoded) && string.IsNullOrEmpty(decoded); } }
        internal static bool IsNullOrEmpty(XmlName xmlName)
        {
            return xmlName == null || xmlName.IsEmpty; 
        }
 
        bool Matches(XmlName xmlName) 
        {
            return string.Equals(this.EncodedName, xmlName.EncodedName, StringComparison.Ordinal); 
        }

        public override bool Equals(object obj)
        { 
            if (object.ReferenceEquals(obj, this))
            { 
                return true; 
            }
 
            if (object.ReferenceEquals(obj, null))
            {
                return false;
            } 

            XmlName xmlName = obj as XmlName; 
            if (xmlName == null) 
            {
                return false; 
            }

            return Matches(xmlName);
        } 

        public override int GetHashCode() 
        { 
            if (string.IsNullOrEmpty(EncodedName))
                return 0; 
            return EncodedName.GetHashCode();
        }

        public override string ToString() 
        {
            if (encoded == null && decoded == null) 
                return null; 
            if (encoded != null)
                return encoded; 
            return decoded;
        }

        public static bool operator ==(XmlName a, XmlName b) 
        {
            if (object.ReferenceEquals(a, null)) 
            { 
                return object.ReferenceEquals(b, null);
            } 

            return (a.Equals(b));
        }
 
        public static bool operator !=(XmlName a, XmlName b)
        { 
            return !(a == b); 
        }
    } 

    static internal class ServiceReflector
    {
        internal const BindingFlags ServiceModelBindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; 
        internal const string BeginMethodNamePrefix = "Begin";
        internal const string EndMethodNamePrefix = "End"; 
        static readonly Type asyncCallbackType = typeof(AsyncCallback); 
        static readonly Type asyncResultType = typeof(IAsyncResult);
        static readonly Type objectType = typeof(object); 

        // returns the set of root interfaces for the service class (meaning doesn't include callback ifaces)

        static internal List GetInterfaces(Type service) 
        {
            List types = new List(); 
            bool implicitContract = false; 
            if (service.IsDefined(typeof(ServiceContractAttribute), false))
            { 
                implicitContract = true;
                types.Add(service);
            }
            if (!implicitContract) 
            {
                Type t = GetAncestorImplicitContractClass(service); 
                if (t != null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxContractInheritanceRequiresInterfaces2, service, t))); 
                }
                foreach (MethodInfo method in GetMethodsInternal(service))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ServicesWithoutAServiceContractAttributeCan2, method.Name, service.FullName))); 
                }
            } 
            foreach (Type t in service.GetInterfaces()) 
            {
                if (t.IsDefined(typeof(ServiceContractAttribute), false)) 
                {
                    if (implicitContract)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxContractInheritanceRequiresInterfaces, service, t))); 
                    }
                    types.Add(t); 
                } 
            }
 
            return types;
        }

        static Type GetAncestorImplicitContractClass(Type service) 
        {
            for (service = service.BaseType; service != null; service = service.BaseType) 
            { 
                if (ServiceReflector.GetSingleAttribute(service) != null)
                { 
                    return service;
                }
            }
            return null; 
        }
 
        static internal List GetInheritedContractTypes(Type service) 
        {
            List types = new List(); 
            foreach (Type t in service.GetInterfaces())
            {
                if (ServiceReflector.GetSingleAttribute(t) != null)
                { 
                    types.Add(t);
                } 
            } 
            for (service = service.BaseType; service != null; service = service.BaseType)
            { 
                if (ServiceReflector.GetSingleAttribute(service) != null)
                {
                    types.Add(service);
                } 
            }
            return types; 
        } 

        static internal object[] GetCustomAttributes(ICustomAttributeProvider attrProvider, Type attrType) 
        {
            return GetCustomAttributes(attrProvider, attrType, false);
        }
 
        static internal object[] GetCustomAttributes(ICustomAttributeProvider attrProvider, Type attrType, bool inherit)
        { 
            try 
            {
                return attrProvider.GetCustomAttributes(attrType, inherit); 
            }
            catch (Exception e)
            {
                if (DiagnosticUtility.IsFatal(e)) 
                {
                    throw; 
                } 

                // where the exception is CustomAttributeFormatException and the InnerException is a TargetInvocationException, 
                // drill into the InnerException as this will provide a better error experience (fewer nested InnerExceptions)
                if (e is CustomAttributeFormatException && e.InnerException != null)
                {
                    e = e.InnerException; 
                    if (e is TargetInvocationException && e.InnerException != null)
                    { 
                        e = e.InnerException; 
                    }
                } 

                Type type = attrProvider as Type;
                MethodInfo method = attrProvider as MethodInfo;
                ParameterInfo param = attrProvider as ParameterInfo; 
                // there is no good way to know if this is a return type attribute
                if (type != null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                        SR.GetString(SR.SFxErrorReflectingOnType2, attrType.Name, type.Name), e)); 
                }
                else if (method != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                        SR.GetString(SR.SFxErrorReflectingOnMethod3,
                                     attrType.Name, method.Name, method.ReflectedType.Name), e)); 
                } 
                else if (param != null)
                { 
                    method = param.Member as MethodInfo;
                    if (method != null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                            SR.GetString(SR.SFxErrorReflectingOnParameter4,
                                         attrType.Name, param.Name, method.Name, method.ReflectedType.Name), e)); 
                    } 
                }
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                    SR.GetString(SR.SFxErrorReflectionOnUnknown1, attrType.Name), e));
            }
        }
 
#if !NO_GENERIC
        static internal T GetSingleAttribute(ICustomAttributeProvider attrProvider) 
            where T : class 
        {
            Type attrType = typeof(T); 
            object[] attrs = GetCustomAttributes(attrProvider, attrType);
            if (attrs.Length == 0)
            {
                return null; 
            }
            else if (attrs.Length > 1) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.tooManyAttributesOfTypeOn2, attrType, attrProvider.ToString())));
            } 
            else
            {
                return attrs[0] as T;
            } 
        }
#else 
        static internal object GetSingleAttribute(Type attrType, ICustomAttributeProvider attrProvider) 
        {
            object[] attrs = GetCustomAttributes(attrProvider, attrType); 
            if (attrs.Length == 0)
            {
                return null;
            } 
            else if (attrs.Length > 1)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.tooManyAttributesOfTypeOn2, attrType, attrProvider.ToString()))); 
            }
            else 
            {
                return attrs[0];
            }
        } 
#endif
#if !NO_GENERIC 
        static internal T GetRequiredSingleAttribute(ICustomAttributeProvider attrProvider) 
            where T : class
        { 
            T result = GetSingleAttribute(attrProvider);
            if (result == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.couldnTFindRequiredAttributeOfTypeOn2, typeof(T), attrProvider.ToString()))); 
            }
            return result; 
        } 
#else
        static internal object GetRequiredSingleAttribute(Type attrType, ICustomAttributeProvider attrProvider) 
        {
            object result = GetSingleAttribute(attrType, attrProvider);
            if (result == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.couldnTFindRequiredAttributeOfTypeOn2, attrType, attrProvider.ToString())));
            } 
            return result; 
        }
#endif 
#if !NO_GENERIC
        static internal T GetSingleAttribute(ICustomAttributeProvider attrProvider, Type[] attrTypeGroup)
            where T : class
        { 
            T result = GetSingleAttribute(attrProvider);
            if (result != null) 
            { 
                Type attrType = typeof(T);
                foreach(Type otherType in attrTypeGroup) 
                {
                    if (otherType == attrType)
                    {
                        continue; 
                    }
                    object[] attrs = GetCustomAttributes(attrProvider, otherType); 
                    if (attrs != null && attrs.Length > 0) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDisallowedAttributeCombination, attrProvider, attrType.FullName, otherType.FullName))); 
                    }
                }
            }
            return result; 
        }
#else 
        static internal object GetSingleAttribute(Type attrType, ICustomAttributeProvider attrProvider, Type[] attrTypeGroup) 
        {
            object result = GetSingleAttribute(attrType, attrProvider); 
            if (result != null)
            {
                foreach (Type otherType in attrTypeGroup)
                { 
                    if (otherType == attrType)
                    { 
                        continue; 
                    }
                    object[] attrs = GetCustomAttributes(attrProvider, otherType); 
                    if (attrs != null && attrs.Length > 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxDisallowedAttributeCombination, attrProvider, attrType.FullName, otherType.FullName)));
                    } 
                }
            } 
            return result; 
        }
#endif 
#if !NO_GENERIC
        static internal T GetRequiredSingleAttribute(ICustomAttributeProvider attrProvider, Type[] attrTypeGroup)
            where T : class
        { 
            T result = GetSingleAttribute(attrProvider, attrTypeGroup);
            if (result == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.couldnTFindRequiredAttributeOfTypeOn2, typeof(T), attrProvider.ToString())));
            } 
            return result;
        }
#else
        static internal object GetRequiredSingleAttribute(Type attrType, ICustomAttributeProvider attrProvider, Type[] attrTypeGroup) 
        {
            object result = GetSingleAttribute(attrType, attrProvider, attrTypeGroup); 
            if (result == null) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.couldnTFindRequiredAttributeOfTypeOn2, attrType, attrProvider.ToString()))); 
            }
            return result;
        }
#endif 
        static internal Type GetContractType(Type interfaceType)
        { 
            ServiceContractAttribute contractAttribute; 
            return GetContractTypeAndAttribute(interfaceType, out contractAttribute);
        } 

        static internal Type GetContractTypeAndAttribute(Type interfaceType, out ServiceContractAttribute contractAttribute)
        {
            contractAttribute = GetSingleAttribute(interfaceType); 
            if (contractAttribute != null)
            { 
                return interfaceType; 
            }
 
            List types = new List(GetInheritedContractTypes(interfaceType));
            if (types.Count == 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AttemptedToGetContractTypeForButThatTypeIs1, interfaceType.Name))); 
            }
 
 
            foreach (Type potentialContractRoot in types)
            { 
                bool mayBeTheRoot = true;
                foreach (Type t in types)
                {
                    if (!t.IsAssignableFrom(potentialContractRoot)) 
                    {
                        mayBeTheRoot = false; 
                    } 
                }
                if (mayBeTheRoot) 
                {
                    contractAttribute = GetSingleAttribute(potentialContractRoot);
                    return potentialContractRoot;
                } 
            }
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException( 
                SR.GetString(SR.SFxNoMostDerivedContract, interfaceType.Name))); 
        }
 
        static List GetMethodsInternal(Type interfaceType)
        {
            List methods = new List();
            foreach (MethodInfo mi in interfaceType.GetMethods(ServiceModelBindingFlags)) 
            {
                if (GetSingleAttribute(mi) != null) 
                { 
                    methods.Add(mi);
                } 
            }
            return methods;
        }
 
        // The metadata for "in" versus "out" seems to be inconsistent, depending upon what compiler generates it.
        // The following code assumes this is the truth table that all compilers will obey: 
        // 
        // True Parameter Type     .IsIn      .IsOut    .ParameterType.IsByRef
        // 
        // in                        F          F         F         ...OR...
        // in                        T          F         F
        //
        // in/out                    T          T         T         ...OR... 
        // in/out                    F          F         T
        // 
        // out                       F          T         T 
        static internal void ValidateParameterMetadata(MethodInfo methodInfo)
        { 
            ParameterInfo[] parameters = methodInfo.GetParameters();
            foreach (ParameterInfo parameter in parameters)
            {
                if (!parameter.ParameterType.IsByRef) 
                {
                    if (parameter.IsOut) 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new InvalidOperationException(SR.GetString(SR.SFxBadByValueParameterMetadata, 
                            methodInfo.Name, methodInfo.DeclaringType.Name)));
                    }
                }
                else 
                {
                    if (parameter.IsIn && !parameter.IsOut) 
                    { 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                            new InvalidOperationException(SR.GetString(SR.SFxBadByReferenceParameterMetadata, 
                            methodInfo.Name, methodInfo.DeclaringType.Name)));
                    }
                }
            } 
        }
 
        static internal bool FlowsIn(ParameterInfo paramInfo)    // conceptually both "in" and "in/out" params return true 
        {
            return !paramInfo.IsOut || paramInfo.IsIn; 
        }
        static internal bool FlowsOut(ParameterInfo paramInfo)   // conceptually both "out" and "in/out" params return true
        {
            return paramInfo.ParameterType.IsByRef; 
        }
 
        // for async method is the begin method 
        static internal ParameterInfo[] GetInputParameters(MethodInfo method, bool asyncPattern)
        { 
            int count = 0;
            ParameterInfo[] parameters = method.GetParameters();

            // length of parameters we care about (-2 for async) 
            int len = parameters.Length;
            if (asyncPattern) 
            { 
                len -= 2;
            } 

            // count the ins
            for (int i = 0; i < len; i++)
            { 
                if (FlowsIn(parameters[i]))
                { 
                    count++; 
                }
            } 

            // grab the ins
            ParameterInfo[] result = new ParameterInfo[count];
            int pos = 0; 
            for (int i = 0; i < len; i++)
            { 
                ParameterInfo param = parameters[i]; 
                if (FlowsIn(param))
                { 
                    result[pos++] = param;
                }
            }
            return result; 
        }
 
        // for async method is the end method 
        static internal ParameterInfo[] GetOutputParameters(MethodInfo method, bool asyncPattern)
        { 
            int count = 0;
            ParameterInfo[] parameters = method.GetParameters();

            // length of parameters we care about (-1 for async) 
            int len = parameters.Length;
            if (asyncPattern) 
            { 
                len -= 1;
            } 

            // count the outs
            for (int i = 0; i < len; i++)
            { 
                if (FlowsOut(parameters[i]))
                { 
                    count++; 
                }
            } 

            // grab the outs
            ParameterInfo[] result = new ParameterInfo[count];
            int pos = 0; 
            for (int i = 0; i < len; i++)
            { 
                ParameterInfo param = parameters[i]; 
                if (FlowsOut(param))
                { 
                    result[pos++] = param;
                }
            }
            return result; 
        }
 
        static internal bool HasOutputParameters(MethodInfo method, bool asyncPattern) 
        {
            ParameterInfo[] parameters = method.GetParameters(); 

            // length of parameters we care about (-1 for async)
            int len = parameters.Length;
            if (asyncPattern) 
            {
                len -= 1; 
            } 

            // count the outs 
            for (int i = 0; i < len; i++)
            {
                if (FlowsOut(parameters[i]))
                { 
                    return true;
                } 
            } 

            return false; 
        }

        static MethodInfo GetEndMethodInternal(MethodInfo beginMethod)
        { 
            string logicalName = GetLogicalName(beginMethod);
            string endMethodName = EndMethodNamePrefix + logicalName; 
            MemberInfo[] endMethods = beginMethod.DeclaringType.GetMember(endMethodName, ServiceModelBindingFlags); 
            if (endMethods.Length == 0)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoEndMethodFoundForAsyncBeginMethod3, beginMethod.Name, beginMethod.DeclaringType.FullName, endMethodName)));
            }
            if (endMethods.Length > 1)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MoreThanOneEndMethodFoundForAsyncBeginMethod3, beginMethod.Name, beginMethod.DeclaringType.FullName, endMethodName)));
            } 
            return (MethodInfo)endMethods[0]; 
        }
 
        static internal MethodInfo GetEndMethod(MethodInfo beginMethod)
        {
            MethodInfo endMethod = GetEndMethodInternal(beginMethod);
 
            if (!HasEndMethodShape(endMethod))
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidAsyncEndMethodSignatureForMethod2, endMethod.Name, endMethod.DeclaringType.FullName))); 
            }
 
            return endMethod;
        }

        static internal XmlName GetOperationName(MethodInfo method) 
        {
            OperationContractAttribute operationAttribute = (OperationContractAttribute)GetRequiredSingleAttribute(method); 
            return NamingHelper.GetOperationName(GetLogicalName(method), operationAttribute.Name); 
        }
 
        static internal bool HasBeginMethodShape(MethodInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters();
            if (!method.Name.StartsWith(BeginMethodNamePrefix, StringComparison.Ordinal) || 
                parameters.Length < 2 ||
                parameters[parameters.Length - 2].ParameterType != asyncCallbackType || 
                parameters[parameters.Length - 1].ParameterType != objectType || 
                method.ReturnType != asyncResultType)
            { 
                return false;
            }
            return true;
        } 

        static internal bool IsBegin(OperationContractAttribute opSettings, MethodInfo method) 
        { 
            if (opSettings.AsyncPattern)
            { 
                if (!HasBeginMethodShape(method))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.InvalidAsyncBeginMethodSignatureForMethod2, method.Name, method.DeclaringType.FullName)));
                } 

                return true; 
            } 
            return false;
        } 

        static internal bool HasEndMethodShape(MethodInfo method)
        {
            ParameterInfo[] parameters = method.GetParameters(); 
            if (!method.Name.StartsWith(EndMethodNamePrefix, StringComparison.Ordinal) ||
                parameters.Length < 1 || 
                parameters[parameters.Length - 1].ParameterType != asyncResultType) 
            {
                return false; 
            }
            return true;
        }
 
        static internal bool IsBegin(MethodInfo method)
        { 
            OperationContractAttribute opSettings = GetSingleAttribute(method); 
            if (opSettings == null)
                return false; 
            return IsBegin(opSettings, method);
        }

        static internal string GetLogicalName(MethodInfo method) 
        {
            return GetLogicalName(method, IsBegin(method)); 
        } 

        static internal string GetLogicalName(MethodInfo method, bool isAsync) 
        {
            if (isAsync)
            {
                return method.Name.Substring(BeginMethodNamePrefix.Length); 
            }
            else 
            { 
                return method.Name;
            } 
        }

        static internal bool HasNoDisposableParameters(MethodInfo methodInfo)
        { 
            foreach (ParameterInfo inputInfo in methodInfo.GetParameters())
            { 
                if (IsParameterDisposable(inputInfo.ParameterType)) 
                {
                    return false; 
                }
            }

            if (methodInfo.ReturnParameter != null) 
            {
                return (!IsParameterDisposable(methodInfo.ReturnParameter.ParameterType)); 
            } 

            return true; 
        }

        static bool IsParameterDisposable(Type type)
        { 
            return ((!type.IsSealed) || typeof(IDisposable).IsAssignableFrom(type));
        } 
    } 
}

// 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