private BindRequest CreateBindRequest(List <ServiceDescriptor> imports, List <ServiceDescriptor> exports) { BindRequest bindRequest = new BindRequest(); foreach (ServiceDescriptor serviceDescriptor in imports) { bindRequest.AddImportedServiceHash(serviceDescriptor.Hash); } uint num = 0u; foreach (ServiceDescriptor serviceDescriptor2 in exports) { num = (serviceDescriptor2.Id = num + 1u); BoundService boundService = new BoundService(); boundService.SetId(serviceDescriptor2.Id); boundService.SetHash(serviceDescriptor2.Hash); bindRequest.AddExportedService(boundService); this.m_rpcConnection.serviceHelper.AddExportedService(serviceDescriptor2.Id, serviceDescriptor2); this.m_logSource.LogDebug("Exporting service id={0} name={1}", new object[] { serviceDescriptor2.Id, serviceDescriptor2.Name }); } return(bindRequest); }
/// <summary> /// Registers the given bound service into this service manager /// </summary> /// <param name="service">The bound service to register</param> /// <returns>The boundID of this service</returns> public int BoundService(BoundService service) { int boundID = this.mNextBoundID++; // add the service to the bound services map this.mBoundServices[boundID] = service; return(boundID); }
/// <summary> /// Takes the given payload and searches in this service manager for the best service match to call the given method /// if possible /// </summary> /// <param name="boundID">The boundID to call at</param> /// <param name="call">The method to call</param> /// <param name="payload">Parameters for the method</param> /// <param name="extraInformation">Any extra information for the method call</param> /// <returns>The result of the call</returns> /// <exception cref="ServiceDoesNotExistsException">If the boundID doesn't match any registered bound service</exception> /// <exception cref="ServiceDoesNotContainCallException">If the service was found but no matching call was found</exception> public PyDataType ServiceCall(int boundID, string call, PyTuple payload, object extraInformation) { BoundService serviceInstance = this.mBoundServices[boundID]; Log.Trace($"Calling {serviceInstance.GetType().Name}::{call} on bound service {boundID}"); if (serviceInstance == null) { throw new ServiceDoesNotExistsException($"Bound Service {boundID}"); } // ensure that only public methods that are part of the instance can be called List <MethodInfo> methods = serviceInstance .GetType() .GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(x => x.Name == call) .ToList(); if (methods.Any() == false) { throw new ServiceDoesNotContainCallException($"(boundID {boundID}) {serviceInstance.GetType().Name}", call, payload); } // relay the exception throw by the call try { foreach (MethodInfo method in methods) { ParameterInfo[] parameters = method.GetParameters(); // ignore functions that do not have enough parameters in them if (parameters.Length < (payload.Count + 1)) { continue; } object[] parameterList = new object[parameters.Length]; // set last parameters as these are the only ones that do not change parameterList[^ 1] = extraInformation;