< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Description.ServiceReflector
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/ServiceReflector.cs
Line coverage
66%
Covered lines: 171
Uncovered lines: 87
Coverable lines: 258
Total lines: 1061
Line coverage: 66.2%
Branch coverage
62%
Covered branches: 121
Total branches: 194
Branch coverage: 62.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/ServiceReflector.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Diagnostics;
 7using System.Globalization;
 8using System.Reflection;
 9using System.Threading;
 10//using System.Xml;
 11using System.Threading.Tasks;
 12using System.Xml;
 13using CoreWCF.Runtime;
 14
 15namespace CoreWCF.Description
 16{
 17    internal static class NamingHelper
 18    {
 19        internal const string DefaultNamespace = "http://tempuri.org/";
 20        internal const string DefaultServiceName = "service";
 21        internal const string MSNamespace = "http://schemas.microsoft.com/2005/07/ServiceModel";
 22
 23        // simplified rules for appending paths to base URIs. note that this differs from new Uri(baseUri, string)
 24        // 1) CombineUriStrings("http://foo/bar/z", "baz") ==> "http://foo/bar/z/baz"
 25        // 2) CombineUriStrings("http://foo/bar/z/", "baz") ==> "http://foo/bar/z/baz"
 26        // 3) CombineUriStrings("http://foo/bar/z", "/baz") ==> "http://foo/bar/z/baz"
 27        // 4) CombineUriStrings("http://foo/bar/z", "http://baz/q") ==> "http://baz/q"
 28        // 5) CombineUriStrings("http://foo/bar/z", "") ==> ""
 29
 30        internal static string CombineUriStrings(string baseUri, string path)
 31        {
 32            if (Uri.IsWellFormedUriString(path, UriKind.Absolute) || path == string.Empty)
 33            {
 34                return path;
 35            }
 36            else
 37            {
 38                // combine
 39                if (baseUri.EndsWith("/", StringComparison.Ordinal))
 40                {
 41                    return baseUri + (path.StartsWith("/", StringComparison.Ordinal) ? path.Substring(1) : path);
 42                }
 43                else
 44                {
 45                    return baseUri + (path.StartsWith("/", StringComparison.Ordinal) ? path : "/" + path);
 46                }
 47            }
 48        }
 49
 50        internal static string TypeName(Type t)
 51        {
 52            if (t.IsGenericType || t.ContainsGenericParameters)
 53            {
 54                Type[] args = t.GetGenericArguments();
 55                int nameEnd = t.Name.IndexOf('`');
 56                string result = nameEnd > 0 ? t.Name.Substring(0, nameEnd) : t.Name;
 57                result += "Of";
 58                for (int i = 0; i < args.Length; ++i)
 59                {
 60                    result = result + "_" + TypeName(args[i]);
 61                }
 62                return result;
 63            }
 64            else if (t.IsArray)
 65            {
 66                return "ArrayOf" + TypeName(t.GetElementType());
 67            }
 68            else
 69            {
 70                return t.Name;
 71            }
 72        }
 73
 74        // name, ns could have any combination of nulls
 75        internal static XmlQualifiedName GetContractName(Type contractType, string name, string ns)
 76        {
 77            XmlName xmlName = new XmlName(name ?? TypeName(contractType));
 78            // ns can be empty
 79            if (ns == null)
 80            {
 81                ns = DefaultNamespace;
 82            }
 83            return new XmlQualifiedName(xmlName.EncodedName, ns);
 84        }
 85
 86        // name could be null
 87        // logicalMethodName is MethodInfo.Name with Begin removed for async pattern
 88        // return encoded version to be used in OperationDescription
 89        internal static XmlName GetOperationName(string logicalMethodName, string name)
 90        {
 91            return new XmlName(string.IsNullOrEmpty(name) ? logicalMethodName : name);
 92        }
 93
 94        //internal static string GetMessageAction(OperationDescription operation, bool isResponse)
 95        //{
 96        //    ContractDescription contract = operation.DeclaringContract;
 97        //    XmlQualifiedName contractQname = new XmlQualifiedName(contract.Name, contract.Namespace);
 98        //    return GetMessageAction(contractQname, operation.CodeName, null, isResponse);
 99        //}
 100
 101        // name could be null
 102        // logicalMethodName is MethodInfo.Name with Begin removed for async pattern
 103        internal static string GetMessageAction(XmlQualifiedName contractName, string opname, string action, bool isResp
 104        {
 105            if (action != null)
 106            {
 107                return action;
 108            }
 109
 110            System.Text.StringBuilder actionBuilder = new System.Text.StringBuilder(64);
 111            if (string.IsNullOrEmpty(contractName.Namespace))
 112            {
 113                actionBuilder.Append("urn:");
 114            }
 115            else
 116            {
 117                actionBuilder.Append(contractName.Namespace);
 118                if (!contractName.Namespace.EndsWith("/", StringComparison.Ordinal))
 119                {
 120                    actionBuilder.Append('/');
 121                }
 122            }
 123            actionBuilder.Append(contractName.Name);
 124            actionBuilder.Append('/');
 125            action = isResponse ? opname + "Response" : opname;
 126
 127            return CombineUriStrings(actionBuilder.ToString(), action);
 128        }
 129
 130        internal delegate bool DoesNameExist(string name, object nameCollection);
 131        internal static string GetUniqueName(string baseName, DoesNameExist doesNameExist, object nameCollection)
 132        {
 133            for (int i = 0; i < int.MaxValue; i++)
 134            {
 135                string name = i > 0 ? baseName + i : baseName;
 136                if (!doesNameExist(name, nameCollection))
 137                {
 138                    return name;
 139                }
 140            }
 141            Fx.Assert("Too Many Names");
 142            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(string.Format(Cultur
 143        }
 144
 145        internal static void CheckUriProperty(string ns, string propName)
 146        {
 147            if (!Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out Uri uri))
 148            {
 149                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.Format(SR.SFXUnvalidNamespaceValue, ns, 
 150            }
 151        }
 152
 153        internal static void CheckUriParameter(string ns, string paramName)
 154        {
 155            if (!Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out Uri uri))
 156            {
 157                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(paramName, SR.Format(SR.SFXUnvalidNamespace
 158            }
 159        }
 160
 161        // Converts names that contain characters that are not permitted in XML names to valid names.
 162        internal static string XmlName(string name)
 163        {
 164            if (string.IsNullOrEmpty(name))
 165            {
 166                return name;
 167            }
 168
 169            if (IsAsciiLocalName(name))
 170            {
 171                return name;
 172            }
 173
 174            if (IsValidNCName(name))
 175            {
 176                return name;
 177            }
 178
 179            return XmlConvert.EncodeLocalName(name);
 180        }
 181
 182        // Transforms an XML name into an object name.
 183        internal static string CodeName(string name)
 184        {
 185            return XmlConvert.DecodeName(name);
 186        }
 187
 188        private static bool IsAlpha(char ch)
 189        {
 190            return (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z');
 191        }
 192
 193        private static bool IsDigit(char ch)
 194        {
 195            return (ch >= '0' && ch <= '9');
 196        }
 197
 198        private static bool IsAsciiLocalName(string localName)
 199        {
 200            Fx.Assert(null != localName, "");
 201            if (!IsAlpha(localName[0]))
 202            {
 203                return false;
 204            }
 205
 206            for (int i = 1; i < localName.Length; i++)
 207            {
 208                char ch = localName[i];
 209                if (!IsAlpha(ch) && !IsDigit(ch))
 210                {
 211                    return false;
 212                }
 213            }
 214            return true;
 215        }
 216
 217        internal static bool IsValidNCName(string name)
 218        {
 219            try
 220            {
 221                XmlConvert.VerifyNCName(name);
 222                return true;
 223            }
 224            catch (XmlException)
 225            {
 226                return false;
 227            }
 228        }
 229    }
 230
 231    [DebuggerDisplay("{_encoded ?? _decoded}")]
 232    internal class XmlName
 233    {
 234        private string _decoded;
 235        private string _encoded;
 236
 237        internal XmlName(string name)
 238            : this(name, false)
 239        {
 240        }
 241
 242        internal XmlName(string name, bool isEncoded)
 243        {
 244            if (isEncoded)
 245            {
 246                ValidateEncodedName(name, true /*allowNull*/);
 247                _encoded = name;
 248            }
 249            else
 250            {
 251                _decoded = name;
 252            }
 253        }
 254
 255        internal string EncodedName
 256        {
 257            get
 258            {
 259                if (_encoded == null)
 260                {
 261                    _encoded = NamingHelper.XmlName(_decoded);
 262                }
 263
 264                return _encoded;
 265            }
 266        }
 267
 268        internal string DecodedName
 269        {
 270            get
 271            {
 272                if (_decoded == null)
 273                {
 274                    _decoded = NamingHelper.CodeName(_encoded);
 275                }
 276
 277                return _decoded;
 278            }
 279        }
 280
 281        private static void ValidateEncodedName(string name, bool allowNull)
 282        {
 283            if (allowNull && name == null)
 284            {
 285                return;
 286            }
 287
 288            try
 289            {
 290                XmlConvert.VerifyNCName(name);
 291            }
 292            catch (XmlException e)
 293            {
 294                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(nameof(name), e.Message);
 295            }
 296        }
 297
 298        private bool IsEmpty { get { return string.IsNullOrEmpty(_encoded) && string.IsNullOrEmpty(_decoded); } }
 299
 300        internal static bool IsNullOrEmpty(XmlName xmlName)
 301        {
 302            return xmlName == null || xmlName.IsEmpty;
 303        }
 304
 305        //    bool Matches(XmlName xmlName)
 306        //    {
 307        //        return string.Equals(this.EncodedName, xmlName.EncodedName, StringComparison.Ordinal);
 308        //    }
 309
 310        //    public override bool Equals(object obj)
 311        //    {
 312        //        if (object.ReferenceEquals(obj, this))
 313        //        {
 314        //            return true;
 315        //        }
 316
 317        //        if (object.ReferenceEquals(obj, null))
 318        //        {
 319        //            return false;
 320        //        }
 321
 322        //        XmlName xmlName = obj as XmlName;
 323        //        if (xmlName == null)
 324        //        {
 325        //            return false;
 326        //        }
 327
 328        //        return Matches(xmlName);
 329        //    }
 330
 331        //    public override int GetHashCode()
 332        //    {
 333        //        if (string.IsNullOrEmpty(EncodedName))
 334        //            return 0;
 335        //        return EncodedName.GetHashCode();
 336        //    }
 337
 338        //    public override string ToString()
 339        //    {
 340        //        if (encoded == null && decoded == null)
 341        //            return null;
 342        //        if (encoded != null)
 343        //            return encoded;
 344        //        return decoded;
 345        //    }
 346
 347        //    public static bool operator ==(XmlName a, XmlName b)
 348        //    {
 349        //        if (object.ReferenceEquals(a, null))
 350        //        {
 351        //            return object.ReferenceEquals(b, null);
 352        //        }
 353
 354        //        return (a.Equals(b));
 355        //    }
 356
 357        //    public static bool operator !=(XmlName a, XmlName b)
 358        //    {
 359        //        return !(a == b);
 360        //    }
 361    }
 362
 363    internal static class ServiceReflector
 364    {
 365        internal const BindingFlags ServiceModelBindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFla
 366        internal const string BeginMethodNamePrefix = "Begin";
 367        internal const string EndMethodNamePrefix = "End";
 368        internal const string AsyncMethodNameSuffix = "Async";
 10369        internal static readonly Type VoidType = typeof(void);
 10370        internal static readonly Type taskType = typeof(Task);
 10371        internal static readonly Type taskTResultType = typeof(Task<>);
 10372        internal static readonly Type CancellationTokenType = typeof(CancellationToken);
 10373        internal static readonly Type IProgressType = typeof(IProgress<>);
 10374        private static readonly Type s_asyncCallbackType = typeof(AsyncCallback);
 10375        private static readonly Type s_asyncResultType = typeof(IAsyncResult);
 10376        private static readonly Type s_objectType = typeof(object);
 10377        private static readonly Type s_operationContractAttributeType = typeof(OperationContractAttribute);
 378        internal const string SMServiceContractAttributeFullName = "System.ServiceModel.ServiceContractAttribute";
 379        internal const string SMOperationContractAttributeFullName = "System.ServiceModel.OperationContractAttribute";
 380        internal const string SMMessageContractAttributeFullName = "System.ServiceModel.MessageContractAttribute";
 381        internal const string SMMessageHeaderAttributeFullName = "System.ServiceModel.MessageHeaderAttribute";
 382        internal const string SMMessageHeaderArrayAttributeFullName = "System.ServiceModel.MessageHeaderArrayAttribute";
 383        internal const string SMMessagePropertyAttributeFullName = "System.ServiceModel.MessagePropertyAttribute";
 384        internal const string SMMessageBodyMemberAttributeFullName = "System.ServiceModel.MessageBodyMemberAttribute";
 385        internal const string SMMessageParameterAttributeFullName = "System.ServiceModel.MessageParameterAttribute";
 386        internal const string SMXmlSerializerFormatAttributeFullName = "System.ServiceModel.XmlSerializerFormatAttribute
 387        internal const string SMFaultContractAttributeFullName = "System.ServiceModel.FaultContractAttribute";
 388        internal const string SMServiceKnownTypeAttributeFullName = "System.ServiceModel.ServiceKnownTypeAttribute";
 389
 390        internal const string CWCFMessageHeaderAttribute = "CoreWCF.MessageHeaderAttribute";
 391        internal const string CWCFMessageHeaderArrayAttribute = "CoreWCF.MessageHeaderArrayAttribute";
 392        internal const string CWCFMessageBodyMemberAttribute = "CoreWCF.MessageBodyMemberAttribute";
 393        internal const string CWCFMessagePropertyAttribute = "CoreWCF.MessagePropertyAttribute";
 394
 395        internal static Type GetOperationContractProviderType(MethodInfo method)
 396        {
 18397            if (GetSingleAttribute<OperationContractAttribute>(method) != null)
 398            {
 0399                return s_operationContractAttributeType;
 400            }
 401
 18402            IOperationContractAttributeProvider provider = GetFirstAttribute<IOperationContractAttributeProvider>(method
 18403            if (provider != null)
 404            {
 0405                return provider.GetType();
 406            }
 407
 18408            return null;
 409        }
 410
 411        internal static bool IsServiceContractAttributeDefined(Type type)
 412        {
 413            // Fast path for CoreWCF.ServiceContractAttribute
 1262414            if (type.IsDefined(typeof(ServiceContractAttribute), false))
 415            {
 554416                return true;
 417            }
 418
 419            // GetCustomAttributesData doesn't traverse the inheritence chain so this is the equivalent of IsDefined(...
 708420            IList<CustomAttributeData> cadList = type.GetCustomAttributesData();
 2212421            foreach (CustomAttributeData cad in cadList)
 422            {
 454423                if (cad.AttributeType.FullName.Equals(SMServiceContractAttributeFullName))
 424                {
 112425                    return true;
 426                }
 427            }
 428
 596429            return false;
 112430        }
 431
 432        // returns the set of root interfaces for the service class (meaning doesn't include callback ifaces)
 433        internal static List<Type> GetInterfaces<TService>() where TService : class
 434        {
 582435            List<Type> types = new List<Type>();
 582436            bool implicitContract = false;
 582437            if (IsServiceContractAttributeDefined(typeof(TService)))
 438            {
 10439                implicitContract = true;
 10440                types.Add(typeof(TService));
 441            }
 442
 582443            if (!implicitContract)
 444            {
 572445                Type t = GetAncestorImplicitContractClass<TService>();
 572446                if (t != null)
 447                {
 0448                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 449                }
 1144450                foreach (MethodInfo method in GetMethodsInternal<TService>())
 451                {
 0452                    Type operationContractProviderType = GetOperationContractProviderType(method);
 0453                    if (operationContractProviderType == s_operationContractAttributeType)
 454                    {
 0455                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Forma
 456                    }
 457                }
 458            }
 2522459            foreach (Type t in typeof(TService).GetInterfaces())
 460            {
 680461                if (IsServiceContractAttributeDefined(t))
 462                {
 656463                    if (implicitContract)
 464                    {
 2465                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Forma
 466                    }
 467
 654468                    types.Add(t);
 469                }
 470            }
 471
 580472            return types;
 473        }
 474
 475        private static Type GetAncestorImplicitContractClass<TService>() where TService : class
 476        {
 2404477            for (Type service = typeof(TService).BaseType; service != null; service = service.BaseType)
 478            {
 630479                if (GetSingleAttribute<ServiceContractAttribute>(service) != null)
 480                {
 0481                    return service;
 482                }
 483            }
 484
 572485            return null;
 486        }
 487
 488        internal static List<Type> GetInheritedContractTypes(Type service)
 489        {
 1356490            List<Type> types = new List<Type>();
 3028491            foreach (Type t in service.GetInterfaces())
 492            {
 158493                if (GetSingleAttribute<ServiceContractAttribute>(t.GetTypeInfo()) != null)
 494                {
 158495                    types.Add(t);
 496                }
 497            }
 2724498            for (service = service.GetTypeInfo().BaseType; service != null; service = service.GetTypeInfo().BaseType)
 499            {
 6500                if (GetSingleAttribute<ServiceContractAttribute>(service.GetTypeInfo()) != null)
 501                {
 0502                    types.Add(service);
 503                }
 504            }
 1356505            return types;
 506        }
 507
 508        internal static object[] GetCustomAttributes(ICustomAttributeProvider attrProvider, Type attrType)
 509        {
 25408510            return GetCustomAttributes(attrProvider, attrType, false);
 511        }
 512
 513        internal static object[] GetCustomAttributes(ICustomAttributeProvider attrProvider, Type attrType, bool inherit)
 514        {
 515            try
 516            {
 44658517                return attrProvider.GetDualCustomAttributes(attrType, inherit) ?? Array.Empty<object>();
 518            }
 2519            catch (Exception e)
 520            {
 2521                if (Fx.IsFatal(e))
 522                {
 0523                    throw;
 524                }
 525
 526                // where the exception is CustomAttributeFormatException and the InnerException is a TargetInvocationExc
 527                // drill into the InnerException as this will provide a better error experience (fewer nested InnerExcep
 2528                if (e is CustomAttributeFormatException && e.InnerException != null)
 529                {
 2530                    e = e.InnerException;
 2531                    if (e is TargetInvocationException && e.InnerException != null)
 532                    {
 2533                        e = e.InnerException;
 534                    }
 535                }
 536
 2537                Type type = attrProvider as Type;
 2538                MethodInfo method = attrProvider as MethodInfo;
 2539                ParameterInfo param = attrProvider as ParameterInfo;
 540                // there is no good way to know if this is a return type attribute
 2541                if (type != null)
 542                {
 0543                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0544                        SR.Format(SR.SFxErrorReflectingOnType2, attrType.Name, type.Name), e));
 545                }
 2546                else if (method != null)
 547                {
 2548                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 2549                    SR.Format(SR.SFxErrorReflectingOnMethod3,
 2550                                     attrType.Name, method.Name, method.ReflectedType.Name), e));
 551                }
 0552                else if (param != null)
 553                {
 0554                    method = param.Member as MethodInfo;
 0555                    if (method != null)
 556                    {
 0557                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0558                            SR.Format(SR.SFxErrorReflectingOnParameter4,
 0559                                         attrType.Name, param.Name, method.Name, method.ReflectedType.Name), e));
 560                    }
 561                }
 0562                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0563                    SR.Format(SR.SFxErrorReflectionOnUnknown1, attrType.Name), e));
 564            }
 44656565        }
 566
 567        internal static T GetFirstAttribute<T>(ICustomAttributeProvider attrProvider)
 568            where T : class
 569        {
 6808570            Type attrType = typeof(T);
 6808571            object[] attrs = GetCustomAttributes(attrProvider, attrType);
 6808572            if (attrs.Length == 0)
 573            {
 6646574                return null;
 575            }
 576            else
 577            {
 162578                return attrs[0] as T;
 579            }
 580        }
 581
 582        internal static T GetSingleAttribute<T>(ICustomAttributeProvider attrProvider) where T : class
 583        {
 16849584            Type attrType = typeof(T);
 16849585            object[] attrs = GetCustomAttributes(attrProvider, attrType);
 16849586            if (attrs.Length == 0)
 587            {
 12051588                return null;
 589            }
 4798590            else if (attrs.Length > 1)
 591            {
 0592                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.too
 593            }
 594            else
 595            {
 4798596                return attrs[0] as T;
 597            }
 598        }
 599
 600        //static internal T GetSingleAttribute<T>(MethodInfo attrProvider)
 601        //    where T : class
 602        //{
 603        //    Type attrType = typeof(T);
 604        //    object[] attrs = GetCustomAttributes(attrProvider, attrType);
 605        //    if (attrs.Length == 0)
 606        //    {
 607        //        return null;
 608        //    }
 609        //    else if (attrs.Length > 1)
 610        //    {
 611        //        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.t
 612        //    }
 613        //    else
 614        //    {
 615        //        return attrs[0] as T;
 616        //    }
 617        //}
 618        //static internal T GetSingleAttribute<T>(ICustomAttributeProvider attrProvider)
 619        //    where T : class
 620        //{
 621        //    Type attrType = typeof(T);
 622        //    object[] attrs = GetCustomAttributes(attrProvider, attrType);
 623        //    if (attrs.Length == 0)
 624        //    {
 625        //        return null;
 626        //    }
 627        //    else if (attrs.Length > 1)
 628        //    {
 629        //        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.t
 630        //    }
 631        //    else
 632        //    {
 633        //        return attrs[0] as T;
 634        //    }
 635        //}
 636
 637        internal static T GetRequiredSingleAttribute<T>(ICustomAttributeProvider attrProvider)
 638            where T : class
 639        {
 834640            T result = GetSingleAttribute<T>(attrProvider);
 834641            if (result == null)
 642            {
 0643                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.cou
 644            }
 834645            return result;
 646        }
 647
 648        internal static T GetSingleAttribute<T>(ICustomAttributeProvider attrProvider, Type[] attrTypeGroup)
 649            where T : class
 650        {
 344651            T result = GetSingleAttribute<T>(attrProvider);
 344652            if (result != null)
 653            {
 324654                Type attrType = typeof(T);
 2334655                foreach (Type otherType in attrTypeGroup)
 656                {
 843657                    if (otherType == attrType)
 658                    {
 659                        continue;
 660                    }
 522661                    object[] attrs = GetCustomAttributes(attrProvider, otherType);
 522662                    if (attrs != null && attrs.Length > 0)
 663                    {
 0664                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Forma
 665                    }
 666                }
 667            }
 344668            return result;
 669        }
 670
 671        internal static T GetRequiredSingleAttribute<T>(ICustomAttributeProvider attrProvider, Type[] attrTypeGroup)
 672            where T : class
 673        {
 86674            T result = GetSingleAttribute<T>(attrProvider, attrTypeGroup);
 86675            if (result == null)
 676            {
 0677                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.cou
 678            }
 86679            return result;
 680        }
 681
 682        //        static internal Type GetContractType(Type interfaceType)
 683        //        {
 684        //            ServiceContractAttribute contractAttribute;
 685        //            return GetContractTypeAndAttribute(interfaceType, out contractAttribute);
 686        //        }
 687
 688        internal static Type GetContractTypeAndAttribute(Type interfaceType, out ServiceContractAttribute contractAttrib
 689        {
 679690            contractAttribute = GetSingleAttribute<ServiceContractAttribute>(interfaceType.GetTypeInfo());
 679691            if (contractAttribute != null)
 692            {
 679693                return interfaceType;
 694            }
 695
 0696            List<Type> types = new List<Type>(GetInheritedContractTypes(interfaceType));
 0697            if (types.Count == 0)
 698            {
 0699                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Att
 700            }
 701
 702
 0703            foreach (Type potentialContractRoot in types)
 704            {
 0705                bool mayBeTheRoot = true;
 0706                foreach (Type t in types)
 707                {
 0708                    if (!t.IsAssignableFrom(potentialContractRoot))
 709                    {
 0710                        mayBeTheRoot = false;
 711                    }
 712                }
 0713                if (mayBeTheRoot)
 714                {
 0715                    contractAttribute = GetSingleAttribute<ServiceContractAttribute>(potentialContractRoot.GetTypeInfo()
 0716                    return potentialContractRoot;
 717                }
 718            }
 0719            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
 0720                SR.Format(SR.SFxNoMostDerivedContract, interfaceType.Name)));
 0721        }
 722
 723        private static List<MethodInfo> GetMethodsInternal<TService>() where TService : class
 724        {
 572725            List<MethodInfo> methods = new List<MethodInfo>();
 14364726            foreach (MethodInfo mi in typeof(TService).GetMethods(ServiceModelBindingFlags))
 727            {
 6610728                if (GetSingleAttribute<OperationContractAttribute>(mi) != null)
 729                {
 0730                    methods.Add(mi);
 731                }
 6610732                else if (GetFirstAttribute<IOperationContractAttributeProvider>(mi) != null)
 733                {
 0734                    methods.Add(mi);
 735                }
 736            }
 572737            return methods;
 738        }
 739
 740        // The metadata for "in" versus "out" seems to be inconsistent, depending upon what compiler generates it.
 741        // The following code assumes this is the truth table that all compilers will obey:
 742        //
 743        // True Parameter Type     .IsIn      .IsOut    .ParameterType.IsByRef
 744        //
 745        // in                        F          F         F         ...OR...
 746        // in                        T          F         F
 747        //
 748        // in/out                    T          T         T         ...OR...
 749        // in/out                    F          F         T
 750        //
 751        // out                       F          T         T
 752        internal static void ValidateParameterMetadata(MethodInfo methodInfo)
 753        {
 2704754            ParameterInfo[] parameters = methodInfo.GetParameters();
 9976755            foreach (ParameterInfo parameter in parameters)
 756            {
 2284757                if (!parameter.ParameterType.IsByRef)
 758                {
 2005759                    if (parameter.IsOut)
 760                    {
 0761                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 0762                            new InvalidOperationException(SR.Format(SR.SFxBadByValueParameterMetadata,
 0763                            methodInfo.Name, methodInfo.DeclaringType.Name)));
 764                    }
 765                }
 766                else
 767                {
 279768                    if (parameter.IsIn && !parameter.IsOut)
 769                    {
 0770                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 0771                            new InvalidOperationException(SR.Format(SR.SFxBadByReferenceParameterMetadata,
 0772                            methodInfo.Name, methodInfo.DeclaringType.Name)));
 773                    }
 774                }
 775            }
 2704776        }
 777
 778        internal static bool FlowsIn(ParameterInfo paramInfo)    // conceptually both "in" and "in/out" params return tr
 779        {
 4583780            return !paramInfo.IsOut || paramInfo.IsIn;
 781        }
 782        internal static bool FlowsOut(ParameterInfo paramInfo)   // conceptually both "out" and "in/out" params return t
 783        {
 4426784            return paramInfo.ParameterType.IsByRef;
 785        }
 786
 787        // for async method is the begin method
 788        internal static ParameterInfo[] GetInputParameters(MethodInfo method, bool asyncPattern)
 789        {
 2687790            int count = 0;
 2687791            ParameterInfo[] parameters = method.GetParameters();
 792
 793            // length of parameters we care about (-2 for async)
 2687794            int len = parameters.Length;
 2687795            if (asyncPattern)
 796            {
 0797                len -= 2;
 798            }
 799
 800            // count the ins
 9938801            for (int i = 0; i < len; i++)
 802            {
 2282803                if (FlowsIn(parameters[i]))
 804                {
 2142805                    count++;
 806                }
 807            }
 808
 809            // grab the ins
 2687810            ParameterInfo[] result = new ParameterInfo[count];
 2687811            int pos = 0;
 9938812            for (int i = 0; i < len; i++)
 813            {
 2282814                ParameterInfo param = parameters[i];
 2282815                if (FlowsIn(param))
 816                {
 2142817                    result[pos++] = param;
 818                }
 819            }
 2687820            return result;
 821        }
 822
 823        // for async method is the end method
 824        internal static ParameterInfo[] GetOutputParameters(MethodInfo method, bool asyncPattern)
 825        {
 2361826            int count = 0;
 2361827            ParameterInfo[] parameters = method.GetParameters();
 828
 829            // length of parameters we care about (-1 for async)
 2361830            int len = parameters.Length;
 2361831            if (asyncPattern)
 832            {
 0833                len -= 1;
 834            }
 835
 836            // count the outs
 8972837            for (int i = 0; i < len; i++)
 838            {
 2125839                if (FlowsOut(parameters[i]))
 840                {
 279841                    count++;
 842                }
 843            }
 844
 845            // grab the outs
 2361846            ParameterInfo[] result = new ParameterInfo[count];
 2361847            int pos = 0;
 8972848            for (int i = 0; i < len; i++)
 849            {
 2125850                ParameterInfo param = parameters[i];
 2125851                if (FlowsOut(param))
 852                {
 279853                    result[pos++] = param;
 854                }
 855            }
 2361856            return result;
 857        }
 858
 859        internal static bool HasOutputParameters(MethodInfo method, bool asyncPattern)
 860        {
 326861            ParameterInfo[] parameters = method.GetParameters();
 862
 863            // length of parameters we care about (-1 for async)
 326864            int len = parameters.Length;
 326865            if (asyncPattern)
 866            {
 0867                len -= 1;
 868            }
 869
 870            // count the outs
 966871            for (int i = 0; i < len; i++)
 872            {
 157873                if (FlowsOut(parameters[i]))
 874                {
 0875                    return true;
 876                }
 877            }
 878
 326879            return false;
 880        }
 881
 882        private static MethodInfo GetEndMethodInternal(MethodInfo beginMethod)
 883        {
 0884            string logicalName = GetLogicalName(beginMethod);
 0885            string endMethodName = EndMethodNamePrefix + logicalName;
 0886            MemberInfo[] endMethods = beginMethod.DeclaringType.GetMember(endMethodName, ServiceModelBindingFlags);
 0887            if (endMethods.Length == 0)
 888            {
 0889                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.NoE
 890            }
 0891            if (endMethods.Length > 1)
 892            {
 0893                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Mor
 894            }
 0895            return (MethodInfo)endMethods[0];
 896        }
 897
 898        internal static MethodInfo GetEndMethod(MethodInfo beginMethod)
 899        {
 0900            MethodInfo endMethod = GetEndMethodInternal(beginMethod);
 901
 0902            if (!HasEndMethodShape(endMethod))
 903            {
 0904                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Inv
 905            }
 906
 0907            return endMethod;
 908        }
 909
 910        //        static internal XmlName GetOperationName(MethodInfo method)
 911        //        {
 912        //            OperationContractAttribute operationAttribute = GetOperationContractAttribute(method);
 913        //            return NamingHelper.GetOperationName(GetLogicalName(method), operationAttribute.Name);
 914        //        }
 915
 916
 917        internal static bool HasBeginMethodShape(MethodInfo method)
 918        {
 0919            ParameterInfo[] parameters = method.GetParameters();
 0920            if (!method.Name.StartsWith(BeginMethodNamePrefix, StringComparison.Ordinal) ||
 0921                parameters.Length < 2 ||
 0922                parameters[parameters.Length - 2].ParameterType != s_asyncCallbackType ||
 0923                parameters[parameters.Length - 1].ParameterType != s_objectType ||
 0924                method.ReturnType != s_asyncResultType)
 925            {
 0926                return false;
 927            }
 0928            return true;
 929        }
 930
 931        internal static bool IsBegin(OperationContractAttribute opSettings, MethodInfo method)
 932        {
 2357933            if (opSettings.AsyncPattern)
 934            {
 0935                if (!HasBeginMethodShape(method))
 936                {
 0937                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 938                }
 939
 0940                return true;
 941            }
 2357942            return false;
 943        }
 944
 945        internal static bool IsTask(MethodInfo method)
 946        {
 0947            if (method.ReturnType == taskType)
 948            {
 0949                return true;
 950            }
 0951            if (method.ReturnType.GetTypeInfo().IsGenericType && method.ReturnType.GetGenericTypeDefinition() == taskTRe
 952            {
 0953                return true;
 954            }
 0955            return false;
 956        }
 957
 958        internal static bool IsTask(MethodInfo method, out Type taskTResult)
 959        {
 2686960            taskTResult = null;
 2686961            Type methodReturnType = method.ReturnType;
 2686962            if (methodReturnType == taskType)
 963            {
 68964                taskTResult = VoidType;
 68965                return true;
 966            }
 967
 2618968            if (methodReturnType.GetTypeInfo().IsGenericType && methodReturnType.GetGenericTypeDefinition() == taskTResu
 969            {
 261970                taskTResult = methodReturnType.GetGenericArguments()[0];
 261971                return true;
 972            }
 973
 2357974            return false;
 975        }
 976
 977        internal static bool HasEndMethodShape(MethodInfo method)
 978        {
 2686979            ParameterInfo[] parameters = method.GetParameters();
 2686980            if (!method.Name.StartsWith(EndMethodNamePrefix, StringComparison.Ordinal) ||
 2686981                parameters.Length < 1 ||
 2686982                parameters[parameters.Length - 1].ParameterType != s_asyncResultType)
 983            {
 2686984                return false;
 985            }
 0986            return true;
 987        }
 988
 989        internal static OperationContractAttribute GetOperationContractAttribute(MethodInfo method)
 990        {
 2704991            OperationContractAttribute operationContractAttribute = GetSingleAttribute<OperationContractAttribute>(metho
 2704992            if (operationContractAttribute != null)
 993            {
 2524994                return operationContractAttribute;
 995            }
 180996            IOperationContractAttributeProvider operationContractProvider = GetFirstAttribute<IOperationContractAttribut
 180997            if (operationContractProvider != null)
 998            {
 162999                return operationContractProvider.GetOperationContractAttribute();
 1000            }
 181001            return null;
 1002        }
 1003
 1004        internal static bool IsBegin(MethodInfo method)
 1005        {
 01006            OperationContractAttribute opSettings = GetOperationContractAttribute(method);
 01007            if (opSettings == null)
 1008            {
 01009                return false;
 1010            }
 1011
 01012            return IsBegin(opSettings, method);
 1013        }
 1014
 1015        internal static string GetLogicalName(MethodInfo method)
 1016        {
 01017            bool isAsync = IsBegin(method);
 01018            bool isTask = isAsync ? false : IsTask(method);
 01019            return GetLogicalName(method, isAsync, isTask);
 1020        }
 1021
 1022        internal static string GetLogicalName(MethodInfo method, bool isAsync, bool isTask)
 1023        {
 26861024            if (isAsync)
 1025            {
 01026                return method.Name.Substring(BeginMethodNamePrefix.Length);
 1027            }
 26861028            else if (isTask && method.Name.EndsWith(AsyncMethodNameSuffix, StringComparison.Ordinal))
 1029            {
 2161030                return method.Name.Substring(0, method.Name.Length - AsyncMethodNameSuffix.Length);
 1031            }
 1032            else
 1033            {
 24701034                return method.Name;
 1035            }
 1036        }
 1037
 1038        internal static bool HasNoDisposableParameters(MethodInfo methodInfo)
 1039        {
 89051040            foreach (ParameterInfo inputInfo in methodInfo.GetParameters())
 1041            {
 21471042                if (IsParameterDisposable(inputInfo.ParameterType))
 1043                {
 7611044                    return false;
 1045                }
 1046            }
 1047
 19251048            if (methodInfo.ReturnParameter != null)
 1049            {
 19251050                return (!IsParameterDisposable(methodInfo.ReturnParameter.ParameterType));
 1051            }
 1052
 01053            return true;
 1054        }
 1055
 1056        internal static bool IsParameterDisposable(Type type)
 1057        {
 40721058            return ((!type.GetTypeInfo().IsSealed) || typeof(IDisposable).IsAssignableFrom(type));
 1059        }
 1060    }
 1061}

Methods/Properties

.cctor()
GetOperationContractProviderType(System.Reflection.MethodInfo)
IsServiceContractAttributeDefined(System.Type)
GetInterfaces()
GetAncestorImplicitContractClass()
GetInheritedContractTypes(System.Type)
GetCustomAttributes(System.Reflection.ICustomAttributeProvider,System.Type)
GetCustomAttributes(System.Reflection.ICustomAttributeProvider,System.Type,System.Boolean)
GetFirstAttribute(System.Reflection.ICustomAttributeProvider)
GetSingleAttribute(System.Reflection.ICustomAttributeProvider)
GetRequiredSingleAttribute(System.Reflection.ICustomAttributeProvider)
GetSingleAttribute(System.Reflection.ICustomAttributeProvider,System.Type[])
GetRequiredSingleAttribute(System.Reflection.ICustomAttributeProvider,System.Type[])
GetContractTypeAndAttribute(System.Type,CoreWCF.ServiceContractAttribute&)
GetMethodsInternal()
ValidateParameterMetadata(System.Reflection.MethodInfo)
FlowsIn(System.Reflection.ParameterInfo)
FlowsOut(System.Reflection.ParameterInfo)
GetInputParameters(System.Reflection.MethodInfo,System.Boolean)
GetOutputParameters(System.Reflection.MethodInfo,System.Boolean)
HasOutputParameters(System.Reflection.MethodInfo,System.Boolean)
GetEndMethodInternal(System.Reflection.MethodInfo)
GetEndMethod(System.Reflection.MethodInfo)
HasBeginMethodShape(System.Reflection.MethodInfo)
IsBegin(CoreWCF.OperationContractAttribute,System.Reflection.MethodInfo)
IsTask(System.Reflection.MethodInfo)
IsTask(System.Reflection.MethodInfo,System.Type&)
HasEndMethodShape(System.Reflection.MethodInfo)
GetOperationContractAttribute(System.Reflection.MethodInfo)
IsBegin(System.Reflection.MethodInfo)
GetLogicalName(System.Reflection.MethodInfo)
GetLogicalName(System.Reflection.MethodInfo,System.Boolean,System.Boolean)
HasNoDisposableParameters(System.Reflection.MethodInfo)
IsParameterDisposable(System.Type)