private void ProjectMethods(EmbeddedItem externalItem, EmbeddingObjectOptions options) { Type type = externalItem.HostType; object obj = externalItem.HostObject; JsValue typeValue = externalItem.ScriptValue; IList <JsNativeFunction> nativeFunctions = externalItem.NativeFunctions; bool instance = externalItem.IsInstance; string typeName = type.FullName; BindingFlags defaultBindingFlags = ReflectionHelpers.GetDefaultBindingFlags(instance); var methods = type.GetMethods(defaultBindingFlags).Select(options.ExtendInfo) .Where((m) => m.IsMapped); var methodGroups = methods.GroupBy(m => m.Name); foreach (var methodGroup in methodGroups) { string methodName = methodGroup.Key; MethodInfo[] methodCandidates = methodGroup.Select(m => m.Info).ToArray(); JsValue nativeFunction(JsValue callee, bool isConstructCall, JsValue[] args, ushort argCount, IntPtr callbackData) { if (instance && obj == null) { CreateAndSetError($"Invalid context while calling method '{methodName}'."); return(JsValue.Undefined); } if (!SelectAndProcessFunction(methodCandidates, args, argCount, out MethodInfo bestSelection, out object[] processedArgs)) { CreateAndSetError($"Suitable method '{methodName}' was not found."); return(JsValue.Undefined); } object result; try { result = bestSelection.Invoke(obj, processedArgs); } catch (Exception e) { Exception exception = UnwrapException(e); var wrapperException = exception as JsException; JsValue errorValue; if (wrapperException != null) { errorValue = CreateErrorFromWrapperException(wrapperException); } else { string errorMessage = instance ? $"Host method '{methodName}' invocation error: {exception.Message}" : $"Host static type '{typeName}' method '{methodName}' invocation error: {exception.Message}" ; errorValue = JsValue.CreateError(JsValue.FromString(errorMessage)); } JsContext.SetException(errorValue); return(JsValue.Undefined); } JsValue resultValue = MapToScriptType(result); return(resultValue); } nativeFunctions.Add(nativeFunction); JsValue methodValue = JsValue.CreateNamedFunction(methodName, nativeFunction); typeValue.SetProperty(methodName, methodValue, true); } }