/// <summary> /// Intended for resolving method calls of types defined in another assembly. /// </summary> /// <param name="owningAsm"></param> /// <param name="tokenName">The name as drafted from <see cref="AssemblyAnalysis.ConvertToMetadataTokenName"/></param> /// <param name="mi"></param> /// <param name="msgOut">Intended for debug trace from the Console.</param> /// <returns></returns> internal bool TryResolveRtMemberInfo(Assembly owningAsm, string tokenName, out MemberInfo mi, StringBuilder msgOut = null) { //default the out variable mi = null; //expect token name to match naming given herein if (String.IsNullOrWhiteSpace(tokenName)) { if (msgOut != null) { msgOut.Append(", Message:'the token name is null'"); } return(false); } if (!tokenName.Contains(Constants.TYPE_METHOD_NAME_SPLIT_ON)) { if (msgOut != null) { msgOut.AppendFormat(", Message:'[{0}] does not contain {1}'", tokenName, Constants.TYPE_METHOD_NAME_SPLIT_ON); } } if (owningAsm == null) { if (msgOut != null) { msgOut.Append(", Message:'the owning assembly is null'"); } return(false); } var assemblyName = owningAsm.GetName().Name; var typeName = MetadataTokenName.CtorTypeNameFromTokenName(tokenName, assemblyName); if (String.IsNullOrWhiteSpace(typeName)) { if (msgOut != null) { msgOut.Append(", Message:'could not parse type name'"); } return(false); } Type asmType = null; try { //framework throwing null-ref ex despite null checks asmType = owningAsm.NfGetType(typeName, false, _myProgram.LogFile); } catch { if (msgOut != null) { msgOut.Append(", Message:'Assembly.GetType threw exception'"); } return(false); } if (asmType == null) { if (msgOut != null) { msgOut.AppendFormat(", Message:'assembly {0} could not resolve {1}'", assemblyName, typeName); } return(false); } var methodName = MetadataTokenName.ParseMethodNameFromTokenName(tokenName); if (String.IsNullOrWhiteSpace(methodName)) { if (msgOut != null) { msgOut.Append(", Message:'could not parse method name'"); } return(false); } MethodInfo methodInfo = null; //try easiest first try { methodInfo = asmType.NfGetMethod(methodName, NfSettings.DefaultFlags); } catch (AmbiguousMatchException) { }//is overloaded //try it the formal way if (methodInfo == null) { var args = MetadataTokenName.ParseArgsFromTokenName(tokenName).ToArray(); var argTypes = args.Length <= 0 ? Type.EmptyTypes : args.Select(Type.GetType).Where(x => x != null).ToArray(); //there must be a one-for-one match of string names to first-class types if (args.Length == argTypes.Length) { methodInfo = asmType.NfGetMethod(methodName, NfSettings.DefaultFlags, null, argTypes, null, false, _myProgram.LogFile); } } //try it the very slow but certain way if (methodInfo == null) { var methodInfos = asmType.NfGetMethods(NfSettings.DefaultFlags, false, _myProgram.LogFile); if (methodInfos.Length <= 0) { if (msgOut != null) { msgOut.AppendFormat(", Assembly:'{0}'\n", assemblyName); msgOut.AppendFormat(", Type:'{0}'\n", typeName); msgOut.Append(", Message:'does not have any methods'"); } return(false); } foreach (var info in methodInfos) { var asTokenName = AssemblyAnalysis.ConvertToMetadataTokenName(info, _myProgram.AsmIndicies, IsIgnore, _myProgram.LogFile); if (asTokenName == null || string.IsNullOrWhiteSpace(asTokenName.Name)) { continue; } if (string.Equals(asTokenName.Name, tokenName)) { methodInfo = info; break; } } } if (methodInfo == null) { if (msgOut != null) { msgOut.AppendFormat(", Assembly:'{0}'\n", assemblyName); msgOut.AppendFormat(", Type:'{0}'\n", typeName); msgOut.AppendFormat(", Method:'{0}'\n", methodName); msgOut.Append(", Message:'was not found'"); } return(false); } mi = methodInfo; return(true); }