예제 #1
0
        public static async Task <MethodProxy> Receive(MethodProxy methodProxy)
        {
            object defaultValue = default(object);

            try
            {
                Type   iface           = methodProxy.InterfaceType.ResolvedType();
                object concreteService = DependencyServiceExtension.Get(iface);

                MethodInfo baseMethod = MethodProxyHelper.GetClassMethodInfo(concreteService.GetType(), iface, methodProxy.MethodIndex);

                //In case of failure, getting Default Return Type
                defaultValue = GetDefault(baseMethod.ReturnType);

                DispatchInvokation(methodProxy, baseMethod, concreteService);

                if (methodProxy.AsyncTask)
                {
                    await((Task)methodProxy.ReturnValue);
                }

                methodProxy.ReturnValue = GetResultFromTask(methodProxy.ReturnType.ResolvedType(), (Task)methodProxy.ReturnValue);
            }
            catch (Exception ex)
            {
                ConsoleHelper.WriteError($"[Native] - {(ex.InnerException != null ? ex.InnerException.Message : ex.Message)}");

                methodProxy.ExceptionDescriptor = new ExceptionDescriptor(ex.InnerException != null ? ex.InnerException : ex);
                methodProxy.ReturnValue         = defaultValue;
                methodProxy.TaskSuccess         = false;
            }

            return(methodProxy);
        }
예제 #2
0
        public static MethodProxy Receive(string methodProxyJson)
        {
            object      defaultValue = default(object);
            MethodProxy methodProxy  = null;

            try
            {
                methodProxy = BridgeSerializer.Deserialize <MethodProxy>(methodProxyJson);

                Type   iface           = methodProxy.InterfaceType.ResolvedType();
                object concreteService = DependencyServiceExtension.Get(iface);

                MethodInfo baseMethod = MethodProxyHelper.GetClassMethodInfo(concreteService.GetType(), iface, methodProxy.MethodIndex);

                //In case of failure, getting Default Return Type
                defaultValue = GetDefault(baseMethod.ReturnType);

                if (methodProxy.GenericTypes != null && methodProxy.GenericTypes.Length > 0)
                {
                    Type[] genericTypes = methodProxy.GenericTypes.Select(p => p.ResolvedType()).ToArray();

                    methodProxy.ReturnValue = baseMethod.MakeGenericMethod(genericTypes).Invoke(concreteService, methodProxy.Parameters);
                    methodProxy.TaskSuccess = true;
                }
                else
                {
                    methodProxy.ReturnValue = baseMethod.Invoke(concreteService, methodProxy.Parameters);
                    methodProxy.TaskSuccess = true;
                }

                if (methodProxy.AsyncTask)
                {
                    methodProxy.ReturnValue = GetResultFromTask(methodProxy.ReturnType.ResolvedType(), (Task)methodProxy.ReturnValue);
                }
            }
            catch (Exception)
            {
                methodProxy.ReturnValue = defaultValue;
                methodProxy.TaskSuccess = false;
            }

            return(methodProxy);
        }
예제 #3
0
        public static MethodProxy Receive(MethodProxy methodProxy)
        {
            object defaultValue = default(object);

            try
            {
                Type   iface           = methodProxy.InterfaceType.ResolvedType();
                object concreteService = DependencyServiceExtension.Get(iface);

                MethodInfo baseMethod = MethodProxyHelper.GetClassMethodInfo(concreteService.GetType(), iface, methodProxy.MethodIndex);

                //In case of failure, getting Default Return Type
                defaultValue = GetDefault(baseMethod.ReturnType);

                if (methodProxy.GenericTypes != null && methodProxy.GenericTypes.Length > 0)
                {
                    Type[] genericTypes = methodProxy.GenericTypes.Select(p => p.ResolvedType()).ToArray();

                    methodProxy.ReturnValue = baseMethod.MakeGenericMethod(genericTypes).Invoke(concreteService, methodProxy.Parameters);
                    methodProxy.TaskSuccess = true;
                }
                else
                {
                    methodProxy.ReturnValue = baseMethod.Invoke(concreteService, methodProxy.Parameters);
                    methodProxy.TaskSuccess = true;
                }

                if (methodProxy.AsyncTask)
                {
                    methodProxy.ReturnValue = GetResultFromTask(methodProxy.ReturnType.ResolvedType(), (Task)methodProxy.ReturnValue);
                }
            }
            catch (Exception ex)
            {
                ConsoleHelper.WriteError($"[Native] - {(ex.InnerException != null ? ex.InnerException.Message : ex.Message)}");

                methodProxy.ExceptionDescriptor = new ExceptionDescriptor(ex.InnerException != null ? ex.InnerException : ex);
                methodProxy.ReturnValue         = defaultValue;
                methodProxy.TaskSuccess         = false;
            }

            return(methodProxy);
        }
예제 #4
0
        public static async Task <MethodProxy> Receive(MethodProxy methodProxy)
        {
            object defaultValue = default(object);

            try
            {
                Type   iface           = methodProxy.InterfaceType.ResolvedType();
                object concreteService = DependencyServiceExtension.Get(iface);

                if (concreteService == null)
                {
                    //iface should not be null
                    string error = $"The service implementation class of your interface '{iface.Name}' was not found on native side. If you are targeting UWP with .NET native toolchain, you must register your services through 'DependencyService.Register' at startup as the toolchain may strip your class from assembly at build time";
                    ConsoleHelper.WriteError(error);
                    throw new InvalidOperationException(error);
                }

                MethodInfo baseMethod = MethodProxyHelper.GetClassMethodInfo(concreteService.GetType(), iface, methodProxy);

                //In case of failure, getting Default Return Type
                defaultValue = GetDefault(baseMethod.ReturnType);

                DispatchInvokation(methodProxy, baseMethod, concreteService);

                if (methodProxy.AsyncTask)
                {
                    await((Task)methodProxy.ReturnValue);
                }

                methodProxy.ReturnValue = GetResultFromTask(methodProxy.ReturnType.ResolvedType(), (Task)methodProxy.ReturnValue);
            }
            catch (Exception ex)
            {
                ConsoleHelper.WriteError($"[Native] - {(ex.InnerException != null ? ex.InnerException.Message : ex.Message)}");

                methodProxy.ExceptionDescriptor = new ExceptionDescriptor(ex.InnerException != null ? ex.InnerException : ex);
                methodProxy.ReturnValue         = defaultValue;
                methodProxy.TaskSuccess         = false;
            }

            return(methodProxy);
        }
예제 #5
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)
            {
                //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
        }
예제 #6
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
        }