| | | 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 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Reflection; |
| | | 7 | | using System.Text; |
| | | 8 | | using System.Linq; |
| | | 9 | | |
| | | 10 | | namespace CoreWCF.Dispatcher; |
| | | 11 | | |
| | | 12 | | public static class DispatchOperationRuntimeHelpers |
| | | 13 | | { |
| | 5063 | 14 | | internal static Dictionary<string, IOperationInvoker> OperationInvokers { get; } = new(); |
| | | 15 | | |
| | | 16 | | public static void RegisterOperationInvoker(string key, IOperationInvoker invoker) |
| | | 17 | | { |
| | 2007 | 18 | | OperationInvokers[key] = invoker; |
| | 2007 | 19 | | } |
| | | 20 | | |
| | | 21 | | internal static string GetKey(MethodInfo method) |
| | | 22 | | { |
| | 3026 | 23 | | StringBuilder stringBuilder = new($"{method.DeclaringType.FullName}.{method.Name}("); |
| | 3026 | 24 | | stringBuilder.Append(string.Join(", ", method.GetParameters().Select(GetParameterString))); |
| | 3026 | 25 | | stringBuilder.Replace("+", "."); |
| | 3026 | 26 | | stringBuilder.Append(")"); |
| | 3026 | 27 | | var result = stringBuilder.ToString(); |
| | 3026 | 28 | | return result; |
| | | 29 | | } |
| | | 30 | | |
| | | 31 | | private static string GetParameterString(ParameterInfo p) |
| | | 32 | | { |
| | 2529 | 33 | | StringBuilder sb = new(); |
| | 2529 | 34 | | Type parameterType = p.ParameterType; |
| | 2529 | 35 | | if (p.IsOut) |
| | | 36 | | { |
| | 140 | 37 | | sb.Append("out "); |
| | 140 | 38 | | parameterType = p.ParameterType.GetElementType(); |
| | | 39 | | } |
| | 2389 | 40 | | else if (p.ParameterType.IsByRef) |
| | | 41 | | { |
| | 139 | 42 | | sb.Append("ref "); |
| | 139 | 43 | | parameterType = p.ParameterType.GetElementType(); |
| | | 44 | | } |
| | | 45 | | |
| | 2529 | 46 | | if (p.IsDefined(typeof(ParamArrayAttribute))) |
| | | 47 | | { |
| | 1 | 48 | | sb.Append("params "); |
| | | 49 | | } |
| | | 50 | | |
| | 2529 | 51 | | string parameterName = GetParameterFullName(parameterType); |
| | 2529 | 52 | | sb.Append(parameterName); |
| | 2529 | 53 | | return sb.ToString(); |
| | | 54 | | } |
| | | 55 | | |
| | | 56 | | private static string GetParameterFullName(Type type) |
| | | 57 | | { |
| | 2572 | 58 | | if (type.IsGenericType) |
| | | 59 | | { |
| | 9 | 60 | | StringBuilder sb = new(); |
| | 9 | 61 | | sb.Append(type.FullName.Substring(0, type.FullName.IndexOf('`'))); |
| | 9 | 62 | | sb.Append("<"); |
| | 9 | 63 | | sb.Append(string.Join(", ", type.GetGenericArguments().Select(GetParameterFullName))); |
| | 9 | 64 | | sb.Append(">"); |
| | 9 | 65 | | return sb.ToString(); |
| | | 66 | | } |
| | | 67 | | |
| | 2563 | 68 | | if (type.IsArray) |
| | | 69 | | { |
| | 30 | 70 | | return GetParameterFullName(type.GetElementType()) + "[]"; |
| | | 71 | | } |
| | | 72 | | |
| | | 73 | | string result; |
| | 2533 | 74 | | if (s_isDynamicCodeSupported.Value) |
| | | 75 | | { |
| | 2533 | 76 | | result = s_runtimeIntegratedTypesMap.TryGetValue(type.TypeHandle.Value, out result) |
| | 2533 | 77 | | ? result |
| | 2533 | 78 | | : type.FullName; |
| | | 79 | | } |
| | | 80 | | else |
| | | 81 | | { |
| | 0 | 82 | | result = s_integratedTypesMap.TryGetValue(type, out result) |
| | 0 | 83 | | ? result |
| | 0 | 84 | | : type.FullName; |
| | | 85 | | } |
| | | 86 | | |
| | 2533 | 87 | | return result; |
| | | 88 | | } |
| | | 89 | | |
| | 30 | 90 | | private static readonly string s_isDynamicCodeSupportedAppContextSwitchKey = "System.Runtime.CompilerServices.Runtim |
| | | 91 | | |
| | 30 | 92 | | private static readonly Lazy<bool> s_isDynamicCodeSupported = new Lazy<bool>(() => |
| | 30 | 93 | | // See https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Runtime/Co |
| | 10 | 94 | | AppContext.TryGetSwitch(s_isDynamicCodeSupportedAppContextSwitchKey, out bool isDynamicCodeSupported) |
| | 10 | 95 | | ? isDynamicCodeSupported |
| | 10 | 96 | | : true |
| | 30 | 97 | | ); |
| | | 98 | | |
| | 30 | 99 | | private static readonly Dictionary<Type, string> s_integratedTypesMap = new() |
| | 30 | 100 | | { |
| | 30 | 101 | | { typeof(bool), "bool" }, |
| | 30 | 102 | | { typeof(byte), "byte" }, |
| | 30 | 103 | | { typeof(sbyte), "sbyte" }, |
| | 30 | 104 | | { typeof(char), "char" }, |
| | 30 | 105 | | { typeof(decimal), "decimal" }, |
| | 30 | 106 | | { typeof(double), "double" }, |
| | 30 | 107 | | { typeof(float), "float" }, |
| | 30 | 108 | | { typeof(int), "int" }, |
| | 30 | 109 | | { typeof(uint), "uint" }, |
| | 30 | 110 | | { typeof(nint), "nint" }, |
| | 30 | 111 | | { typeof(nuint), "nuint" }, |
| | 30 | 112 | | { typeof(long), "long" }, |
| | 30 | 113 | | { typeof(ulong), "ulong" }, |
| | 30 | 114 | | { typeof(short), "short" }, |
| | 30 | 115 | | { typeof(ushort), "ushort" }, |
| | 30 | 116 | | { typeof(object), "object" }, |
| | 30 | 117 | | { typeof(string), "string" } |
| | 30 | 118 | | }; |
| | | 119 | | |
| | 30 | 120 | | private static readonly Dictionary<IntPtr, string> s_runtimeIntegratedTypesMap = s_integratedTypesMap |
| | 1050 | 121 | | .ToDictionary(kvp => kvp.Key.TypeHandle.Value, kvp => kvp.Value); |
| | | 122 | | } |