private static Task <TReturnType> InternalCallMethod <TReturnType>(MethodBase methodBase, Type[] genericParameters, object[] args, bool isAsync)
        {
            MethodInfo method = (MethodInfo)methodBase;

            if (genericParameters == null)
            {
                genericParameters = new Type[0];
            }

            if (args == null)
            {
                args = new object[0];
            }

            #region Invokation

            MethodProxy methodProxy = new MethodProxy();

            var iface = methodBase.DeclaringType.GetInterfaces().FirstOrDefault(p => p.GetCustomAttribute <ProxyInterfaceAttribute>() != null);

            if (iface == null)
            {
                //First exception chance. We are maybe in an Async task context. Trying to retrieve base method
                MethodBase noAsyncMethodBase = GetRealMethodBaseFromAsyncMethod(methodBase);

                if (noAsyncMethodBase != null)
                {
                    //Replacing local references by the found one
                    methodBase = noAsyncMethodBase;
                    method     = (MethodInfo)methodBase;
                    iface      = methodBase.DeclaringType.GetInterfaces().FirstOrDefault(p => p.GetCustomAttribute <ProxyInterfaceAttribute>() != null);
                }
            }

            if (iface == null)
            {
                throw new ArgumentException("Unable to find the method to call on the interface. Be sure to add the [ProxyInterface] attribute on top of your interface definition. If using MethodBase.GetCurrentMethod(), check that your calling method is not marked as 'async', as it may hide the real method definition.");
            }

            //As we are using a DispatchProxy, the targetMethod should be the interface MethodInfo (and not a class MethodInfo)
            int index = MethodProxyHelper.GetInterfaceMethodIndex(methodBase.DeclaringType, method, iface);

            if (index == -1)
            {
                return(Task.FromResult(default(TReturnType)));
            }

            //Only used with UWP that does not support GetInterfaceMap calls with .NET Native toolchain
            //Other implementation will call the method according to the method index
            methodProxy.MethodName = method.Name;

            methodProxy.MethodIndex  = index;
            methodProxy.GenericTypes = genericParameters.Select(p => new TypeProxy(p)).ToArray();

            //On this case, the DeclaringType should be the Interface type
            methodProxy.InterfaceType = new TypeProxy(iface);

            methodProxy.ReturnType = new TypeProxy(typeof(TReturnType));

            //NOTE: We must flag if the current Task is Async or not, as explicit Async method must wrap the result out on a Task.FromResult.
            //This way, the Receive dispatcher know that it must Serialize the Task result, and not the Task object itself
            methodProxy.AsyncTask = isAsync;

            //We will let the serializer do the thing for RunTime values
            methodProxy.Parameters = args;

            Task <TReturnType> task = Task.FromResult(default(TReturnType));

            //TODO: Should refactorate in order to avoid copy/past for this switch
            switch (ContextHelper.GetExecutingContext())
            {
            case Models.ExecutingContext.Blazor:
                task = CreateTaskDispatcher <TReturnType>(methodProxy);
                BlazorToXamarinDispatcher.Send(methodProxy);
                break;

            case Models.ExecutingContext.ElectronNET:
                task = CreateTaskDispatcher <TReturnType>(methodProxy);
                BlazorToElectronNETDispatcher.Send(methodProxy);
                break;
            }

            return(task);

            #endregion
        }
Exemple #2
0
        private static Task <TReturnType> InternalCallMethod <TReturnType>(MethodBase methodBase, Type[] genericParameters, object[] args, bool isAsync)
        {
            MethodInfo method = (MethodInfo)methodBase;

            if (genericParameters == null)
            {
                genericParameters = new Type[0];
            }

            if (args == null)
            {
                args = new object[0];
            }

            #region Invokation

            MethodProxy methodProxy = new MethodProxy();

            var iface = methodBase.DeclaringType.GetInterfaces().FirstOrDefault(p => p.GetCustomAttribute <ProxyInterfaceAttribute>() != null);
            if (iface == null)
            {
                throw new ArgumentException("Given class method does not contain any possible ProxyInterface. Be sure to add [ProxyInterface] attribute on top of your interface definition");
            }

            //As we are using a DispatchProxy, the targetMethod should be the interface MethodInfo (and not a class MethodInfo)
            int index = MethodProxyHelper.GetInterfaceMethodIndex(methodBase.DeclaringType, method, iface);

            if (index == -1)
            {
                return(Task.FromResult(default(TReturnType)));
            }

            methodProxy.MethodIndex  = index;
            methodProxy.GenericTypes = genericParameters.Select(p => new TypeProxy(p)).ToArray();

            //On this case, the DeclaringType should be the Interface type
            methodProxy.InterfaceType = new TypeProxy(iface);

            methodProxy.ReturnType = new TypeProxy(typeof(TReturnType));

            //NOTE: We must flag if the current Task is Async or not, as explicit Async method must wrap the result out on a Task.FromResult.
            //This way, the Receive dispatcher know that it must Serialize the Task result, and not the Task object itself
            methodProxy.AsyncTask = isAsync;

            //We will let the serializer do the thing for RunTime values
            methodProxy.Parameters = args;

            switch (ContextHelper.GetExecutingContext())
            {
            case Models.ExecutingContext.Blazor:
                int taskId = 0;
                var task   = CreateTaskDispatcher <TReturnType>(out taskId);

                methodProxy.TaskIdentity = taskId;

                BlazorToXamarinDispatcher.Send(methodProxy);

                return(task);

            default:
                return(Task.FromResult(default(TReturnType)));
            }

            #endregion
        }