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 }
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 }