Example #1
0
        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            Log.Debug("[MethodProxy.Invoke] " + (new MethodCallInfo()
            {
                Name = targetMethod.Name, Args = args.ToList()
            }).ToString());

            bool          IsIInvokeProxy = _invokeType == InvokeType.Proxy || _invokeType == InvokeType.ProxyFunc;
            IInvokerProxy invoker;

            switch (_invokeType)
            {
            case InvokeType.Proxy:
                invoker = _invokerProxy;
                break;

            case InvokeType.ProxyFunc:
                invoker = GetIInvokerProxyFunc();
                break;

            default:
                invoker = null;
                break;
            }

            if (IsIInvokeProxy || BeforeInvoke != null)
            {
                BeforeInvokeEventArgs beforeArgs = new BeforeInvokeEventArgs()
                {
                    MethodInfo = targetMethod,
                    Args       = args,
                };
                BeforeInvoke?.Invoke(this, beforeArgs);
                invoker?.BeforeInvoke(this, beforeArgs);
                if (beforeArgs.Handled)
                {
                    return(beforeArgs.FakeResult);
                }
            }

            object result;

            if (IsIInvokeProxy)
            {
                result = invoker.Invoke(targetMethod, args);
            }
            else if (_invokeType == InvokeType.Object)
            {
                result = targetMethod.Invoke(_invokeObject, args);
            }
            else
            {
                throw new Exception("InvokeProxy: unknown InvokeType");
            }

            if (result is Task task)
            {
                if (targetMethod.ReturnType.IsGenericType)
                {
                    Type type = targetMethod.ReturnType.GetGenericArguments()[0];
                    if (TypeHelper.IsType(task, typeof(Task <object>)))
                    {
                        result = TaskHelper.ConvertTaskObject((Task <object>)task, type);
                    }
                    else
                    {
                        // e.g. UnwrapPromise<object>
                        var generic_task = TaskHelper.ConvertTaskReturnObject(task);
                        result = TaskHelper.ConvertTaskObject(generic_task, type);
                    }
                }
                else
                {
                    Task.Run(async() => await task);
                    result = Task.CompletedTask;
                }
            }

            TypeHelper.AssertType(result, targetMethod.ReturnType);

            if (IsIInvokeProxy || AfterInvoke != null)
            {
                AfterInvokeEventArgs afterArgs = new AfterInvokeEventArgs()
                {
                    MethodInfo = targetMethod,
                    Args       = args,
                    Result     = result,
                };
                AfterInvoke?.Invoke(this, afterArgs);
                invoker?.AfterInvoke(this, afterArgs);
            }
            return(result);
        }