public async Task<ConsumerExecutedResult> InvokeAsync(ConsumerContext context, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var methodInfo = context.ConsumerDescriptor.MethodInfo; var reflectedTypeHandle = methodInfo.ReflectedType.TypeHandle.Value; var methodHandle = methodInfo.MethodHandle.Value; var key = $"{reflectedTypeHandle}_{methodHandle}"; var executor = _executors.GetOrAdd(key, x => ObjectMethodExecutor.Create(methodInfo, context.ConsumerDescriptor.ImplTypeInfo)); using var scope = _serviceProvider.CreateScope(); var provider = scope.ServiceProvider; var obj = GetInstance(provider, context); var message = context.DeliverMessage; var parameterDescriptors = context.ConsumerDescriptor.Parameters; var executeParameters = new object[parameterDescriptors.Count]; for (var i = 0; i < parameterDescriptors.Count; i++) { var parameterDescriptor = parameterDescriptors[i]; if (parameterDescriptor.IsFromCap) { executeParameters[i] = GetCapProvidedParameter(parameterDescriptor, message, cancellationToken); } else { if (message.Value != null) { if (_serializer.IsJsonType(message.Value)) // use ISerializer when reading from storage, skip other objects if not Json { executeParameters[i] = _serializer.Deserialize(message.Value, parameterDescriptor.ParameterType); } else { var converter = TypeDescriptor.GetConverter(parameterDescriptor.ParameterType); if (converter.CanConvertFrom(message.Value.GetType())) { executeParameters[i] = converter.ConvertFrom(message.Value); } else { if (parameterDescriptor.ParameterType.IsInstanceOfType(message.Value)) { executeParameters[i] = message.Value; } else { executeParameters[i] = Convert.ChangeType(message.Value, parameterDescriptor.ParameterType); } } } } } } var filter = provider.GetService<ISubscribeFilter>(); object resultObj = null; try { if (filter != null) { var etContext = new ExecutingContext(context, executeParameters); filter.OnSubscribeExecuting(etContext); executeParameters = etContext.Arguments; } resultObj = await ExecuteWithParameterAsync(executor, obj, executeParameters); if (filter != null) { var edContext = new ExecutedContext(context, resultObj); filter.OnSubscribeExecuted(edContext); resultObj = edContext.Result; } } catch (Exception e) { if (filter != null) { var exContext = new ExceptionContext(context, e); filter.OnSubscribeException(exContext); if (!exContext.ExceptionHandled) { throw exContext.Exception; } if (exContext.Result != null) { resultObj = exContext.Result; } } else { throw; } } return new ConsumerExecutedResult(resultObj, message.GetId(), message.GetCallbackName()); }
public async Task <ConsumerExecutedResult> InvokeAsync(ConsumerContext context, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); var methodInfo = context.ConsumerDescriptor.MethodInfo; var reflectedType = methodInfo.ReflectedType.Name; _logger.LogDebug("Executing subscriber method : {0}", methodInfo.Name); var key = $"{methodInfo.Module.Name}_{reflectedType}_{methodInfo.MetadataToken}"; var executor = _executors.GetOrAdd(key, x => ObjectMethodExecutor.Create(methodInfo, context.ConsumerDescriptor.ImplTypeInfo)); using (var scope = _serviceProvider.GetService <ICapServiceScope>()) { var obj = scope.GetInstance(context); var message = context.DeliverMessage; var parameterDescriptors = context.ConsumerDescriptor.Parameters; var executeParameters = new object[parameterDescriptors.Count]; for (var i = 0; i < parameterDescriptors.Count; i++) { if (parameterDescriptors[i].IsFromCap) { executeParameters[i] = new CapHeader(message.Headers); } else { if (message.Value != null) { if (_serializer.IsJsonType(message.Value)) // use ISerializer when reading from storage, skip other objects if not Json { executeParameters[i] = _serializer.Deserialize(message.Value, parameterDescriptors[i].ParameterType); } else { var converter = TypeDescriptor.GetConverter(parameterDescriptors[i].ParameterType); if (converter.CanConvertFrom(message.Value.GetType())) { executeParameters[i] = converter.ConvertFrom(message.Value); } else { if (parameterDescriptors[i].ParameterType.IsInstanceOfType(message.Value)) { executeParameters[i] = message.Value; } else { executeParameters[i] = Convert.ChangeType(message.Value, parameterDescriptors[i].ParameterType); } } } } } } var resultObj = await ExecuteWithParameterAsync(executor, obj, executeParameters); return(new ConsumerExecutedResult(resultObj, message.GetId(), message.GetCallbackName())); } }