public static object InvokeMethod(object instance, string methodName, IServiceProvider services, IReadOnlyDictionary <string, object> options, params object[] parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (methodName == null)
            {
                throw new ArgumentNullException(nameof(methodName));
            }
            if (options == null)
            {
                return(InvokeMethod(instance, methodName, services, parameters));
            }
            if (services == null)
            {
                return(InvokeMethod(instance, methodName, options, parameters));
            }

            Type instanceType = instance.GetType();

            MethodInfo[] methods = instanceType.GetMethodOverloads(methodName, false);
            if (methods.Length <= 0)
            {
                throw new InvalidOperationException("cannot find method {methodName} of instance {instance}");
            }

            IEnumerable <ArgumentMatchedResult> matchResults = null;

            if (parameters.Length > 0)
            {
                matchResults = methods.Select(m => ArgumentMatchedResult.Match(m, services, options, parameters));
            }
            else
            {
                matchResults = methods.Select(m => ArgumentMatchedResult.Match(m, services, options));
            }

            ArgumentMatchedResult matchResult = FindBestMatch(matchResults);

            if (matchResult == null)
            {
                throw new InvalidOperationException($"cannot find any method {methods[0].Name} of instance {instance} that matchs given parameters");
            }
            InvokeMethodResult result = TryInvokeMethod(instance, matchResult);

            if (result.IsExecutionSucceeded == false)
            {
                throw result.Exception;
            }
            if (result.HasReturnValueBySignature == false)
            {
                return(null);
            }
            else
            {
                return(result.ReturnValue);
            }
        }
        public static object InvokeMethod(object instance, MethodInfo method, IServiceProvider services, IReadOnlyDictionary <string, object> options, params object[] parameters)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }
            if (options == null)
            {
                return(InvokeMethod(instance, method, services, parameters));
            }
            if (services == null)
            {
                return(InvokeMethod(instance, method, options, parameters));
            }

            ArgumentMatchedResult matchResult = null;

            if (parameters.Length > 0)
            {
                matchResult = ArgumentMatchedResult.Match(method, services, options, parameters);
            }
            else
            {
                matchResult = ArgumentMatchedResult.Match(method, services, options);
            }
            InvokeMethodResult result = TryInvokeMethod(instance, matchResult);

            if (result.IsExecuted == false)
            {
                throw new InvalidOperationException("cannot invoke method due to insufficient parameters");
            }
            if (result.IsExecutionSucceeded == false)
            {
                throw result.Exception;
            }
            if (result.HasReturnValueBySignature == false)
            {
                return(null);
            }
            else
            {
                return(result.ReturnValue);
            }
        }
        public async Task <IList <Condition> > GetConditions()
        {
            lock (Context.Current.Locks["Conditions"])
            {
                Conditions.Clear();
            }
            if (IsConnected)
            {
                InvokeMethodResult result = await _getConditions.InvokeAsync(new List <object>());

                var values = result.Values;
                if (!string.IsNullOrEmpty(values[0] as string))
                {
                    string[] sourceTypes    = ((string)values[0]).Split(new[] { ";" }, StringSplitOptions.None);
                    string[] sourceNames    = ((string)values[1]).Split(new[] { ";" }, StringSplitOptions.None);
                    string[] targetNames    = ((string)values[2]).Split(new[] { ";" }, StringSplitOptions.None);
                    string[] requiredValues = ((string)values[3]).Split(new[] { ";" }, StringSplitOptions.None);
                    string[] conditionTypes = ((string)values[4]).Split(new[] { ";" }, StringSplitOptions.None);
                    string[] targetValues   = ((string)values[5]).Split(new[] { ";" }, StringSplitOptions.None);

                    if (sourceTypes != null)
                    {
                        lock (Context.Current.Locks["Conditions"])
                        {
                            for (int i = 0; i < sourceTypes.Length - 1; i++)
                            {
                                Conditions.Add(new Condition()
                                {
                                    SourceDeviceType = (DeviceType)Convert.ToInt32(sourceTypes[i]),
                                    SourceDeviceName = sourceNames[i],
                                    TargetDeviceName = targetNames[i],
                                    RequiredValue    = Convert.ToInt32(requiredValues[i]),
                                    ConditionType    = (ConditionType)Convert.ToInt32(conditionTypes[i]),
                                    TargetValue      = Convert.ToInt32(targetValues[i])
                                });
                            }
                        }
                    }
                }
            }
            return(Conditions);
        }
        private static InvokeMethodResult TryInvokeMethod(object instance, ArgumentMatchedResult matchResult)
        {
            MethodInfo method = matchResult.Method as MethodInfo;

            if (!matchResult.IsPassed)
            {
                return(InvokeMethodResult.MethodNotFound());
            }

            try
            {
                object returnValue = method.Invoke(instance, matchResult.Result);
                return(InvokeMethodResult.Success(method.ReturnType, returnValue));
            }
            catch (TargetInvocationException ex)
            {
                return(InvokeMethodResult.Failed(ex.InnerException));
            }
            catch
            {
                throw;
            }
        }
Example #5
0
            private void ServiceJoined(IService service)
            {
                // Don't continue if the new service isn't the one we're interested in.
                if (DeviceId != "*" && service.AboutData.DeviceId != DeviceId)
                {
                    return;
                }

                // Prepare the interaction.

                IEnumerable <IBusObject> busObjects = new List <IBusObject>();

                if (Path == "*")
                {
                    // Get everything
                    try
                    {
                        busObjects = service.AllObjects().Where(x => x.Interfaces != null && x.Interfaces.Any(y => y.Name == InterfaceName));
                    }
                    catch (Exception ex)
                    {
                        Logger.LogException("Interaction", ex);
                    }
                }
                else
                {
                    try
                    {
                        // DEMO TEMP FIX:
                        // Replace with IService::GetBusObject()
                        busObjects = new List <IBusObject>()
                        {
                            service.AllObjects().First(x => x.Path == Path)
                        };
                    }
                    catch (InvalidOperationException)
                    {
                        failDiscovery("Couldn't find bus object: " + Path);
                        return;
                    }
                }

                foreach (IBusObject busObject in busObjects)
                {
                    IInterface @interface;
                    int        delayMSec = 0;

                    try
                    {
                        @interface = busObject.Interfaces.First(x => x.Name == InterfaceName);
                    }
                    catch (InvalidOperationException)
                    {
                        failDiscovery(busObject.Path + ", couldn't find interface: " + InterfaceName);
                        return;
                    }

                    if (InteractionConfig.ContainsKey("delay"))
                    {
                        try
                        {
                            delayMSec = (int)InteractionConfig["delay"].GetNumber();
                        }
                        catch (InvalidCastException)
                        {
                            failDiscovery("Couldn't cast delay value: " + InteractionConfig.GetNamedString("delay"));
                        }
                    }

                    if (InteractionConfig.ContainsKey("propertyName"))
                    {
                        IProperty property = null;
                        object    newValue = null;

                        try
                        {
                            property = @interface.Properties.First(x => x.Name == InteractionConfig.GetNamedString("propertyName"));
                        }
                        catch (InvalidOperationException)
                        {
                            failDiscovery("Couldn't find property: " + InteractionConfig.GetNamedString("propertyName"));
                            return;
                        }

                        try
                        {
                            newValue = AllJoynTypes.Convert(property.TypeInfo, InteractionConfig["propertyValue"]);
                        }
                        catch (InvalidCastException)
                        {
                            failDiscovery("Couldn't cast property value for property: " + InteractionConfig.GetNamedString("propertyName"));
                            return;
                        }

                        Actions.Add(
                            async() =>
                        {
                            if (delayMSec > 0)
                            {
                                await System.Threading.Tasks.Task.Delay(delayMSec);
                            }

                            AllJoynStatus status = await property?.SetValueAsync(newValue);

                            if (status == null || status.IsFailure)
                            {
                                throw Logger.LogException(service.Name,
                                                          new InvalidOperationException(
                                                              string.Format("{0} - Couldn't modify property: {1}", status, property.Name)
                                                              )
                                                          );
                            }
                        }
                            );
                    }
                    else if (InteractionConfig.ContainsKey("methodName"))
                    {
                        IMethod       method     = null;
                        List <object> methodArgs = null;

                        try
                        {
                            method = @interface.Methods.First(x => x.Name == InteractionConfig.GetNamedString("methodName"));
                        }
                        catch (InvalidOperationException)
                        {
                            failDiscovery("Couldn't find method: " + InteractionConfig.GetNamedString("methodName"));
                            return;
                        }

                        try
                        {
                            methodArgs = Enumerable.Zip(method.InSignature,
                                                        InteractionConfig.GetNamedArray("methodArguments"),
                                                        (t, x) => AllJoynTypes.Convert(t.TypeDefinition, x)
                                                        ).ToList();
                        }
                        catch (InvalidCastException)
                        {
                            failDiscovery("Couldn't cast arguments for method: " + InteractionConfig.GetNamedString("methodName"));
                            return;
                        }

                        Actions.Add(
                            async() =>
                        {
                            if (delayMSec > 0)
                            {
                                await System.Threading.Tasks.Task.Delay(delayMSec);
                            }

                            InvokeMethodResult status = await method?.InvokeAsync(methodArgs);

                            if (status == null || status.Status.IsFailure)
                            {
                                throw Logger.LogException(service.Name,
                                                          new InvalidOperationException(
                                                              string.Format("{0} - Couldn't invoke method: {1}", status, method.Name)
                                                              )
                                                          );
                            }
                        }
                            );
                    }
                    else
                    {
                        failDiscovery("Interaction does not have property nor method information.");
                        return;
                    }
                }
            }