コード例 #1
0
        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);
            }
        }