public static void GetParameters(this MethodInfo mi, int ignoreCount, out ManagementParamAttribute[] attributes, out DataType[] paramTypes) { ParameterInfo[] paramInfos = mi.GetParameters(); int count = paramInfos.Length - ignoreCount; attributes = new ManagementParamAttribute[count]; paramTypes = new DataType[count]; for (int i = 0; i < count; i++) { if (paramInfos[i].ParameterType.IsGenericParameter) { throw new NotSupportedException("Generic parameter not supported for " + paramInfos[i].Name); } var paramAttribute = paramInfos[i].GetCustomAttribute <ManagementParamAttribute>(); if (paramAttribute == null) { paramAttribute = new ManagementParamAttribute(); } if (paramAttribute.Name == null) { paramAttribute.Name = paramInfos[i].Name; } attributes[i] = paramAttribute; paramTypes[i] = DataType.Wrap(paramInfos[i].ParameterType); } }
public async Task <object> Start() { RequestResponseAmqpLink requestLink = await this.client.link.GetOrCreateAsync(TimeSpan.FromMinutes(1)); ApplicationProperties properties = new ApplicationProperties(); properties.Map[AmqpClientConstants.ManagementOperationKey] = this.md.Operation.Name; // generate message sections containing the arguments // convert custom-type parameters if needed object bodyValue = null; AmqpMap bodyMap = null; for (int i = 0; i < this.argCount; i++) { ManagementParamAttribute paramAttribute = this.md.Parameters[i]; object value = SerializationHelper.ToAmqp(this.md.ParameterTypes[i].Serializable, this.mcm.InArgs[i]); if (paramAttribute.Location == ManagementParamLocation.ApplicationProperties) { properties.Map[paramAttribute.Name] = value; } else if (paramAttribute.Location == ManagementParamLocation.MapBody) { if (bodyMap == null) { bodyMap = new AmqpMap(); } bodyMap[new MapKey(paramAttribute.Name)] = value; } else { bodyValue = value; } } // Upsert link RequestProperties to ApplicationProperties foreach (var requestProperty in requestLink.RequestProperties) { properties.Map[requestProperty.Key] = requestProperty.Value; } this.request = AmqpMessage.Create(new AmqpValue { Value = bodyMap ?? bodyValue }); this.request.ApplicationProperties = properties; this.response = await requestLink.RequestAsync(request, TimeSpan.FromMinutes(1)); int statusCode = (int)this.response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode]; string statusDescription = (string)this.response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription]; if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK) { AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(this.response, (AmqpResponseStatusCode)statusCode); Error error = new Error { Condition = errorCondition, Description = statusDescription }; throw new AmqpException(error); } object returnValue = null; if (this.response.ValueBody != null) { returnValue = this.response.ValueBody.Value; } if (md.ReturnType.HasValue && returnValue != null) { Type expected = md.ReturnType.Type; SerializableType serializable = md.ReturnType.Serializable; if (serializable == null) { // must be a generic parameter expected = mcm.GenericTypes[md.ReturnType.Type.GenericParameterPosition]; serializable = expected.GetSerializable(); } returnValue = SerializationHelper.FromAmqp(serializable, returnValue); if (!expected.IsAssignableFrom(returnValue.GetType())) { throw new InvalidOperationException($"Return type mismatch in {mcm.MethodBase.Name}. Expect {expected.Name} Actual {returnValue.GetType().Name}"); } } return(returnValue); }