예제 #1
0
        public IEnumerable <IAsyncSubscription> Subscribe(IConnection connection)
        {
            foreach (var method in ContractType.GetMethods())
            {
                var methodRoute  = $"{HandlerRoute}.{method.Name}";
                var subscription = connection.SubscribeAsync(methodRoute);

                subscription.MessageHandler += async(sender, args) =>
                {
                    try
                    {
                        var parameterTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
                        var arguments      = _deserialzer.DeserialzeObjects(args.Message.Data, parameterTypes);

                        object result;

                        using (var scope = _serviceProvider.CreateScope())
                        {
                            var contractImplementaion = _contractImplFactory.Invoke(scope.ServiceProvider, Array.Empty <object>());
                            result = method.Invoke(contractImplementaion, arguments);

                            if (typeof(Task).IsAssignableFrom(method.ReturnType))
                            {
                                var task = (Task)result;

                                await task;

                                var prop = method.ReturnType.GetProperty("Result");
                                result = prop?.GetValue(task);
                            }
                        }

                        var bytes = _serializer.SerializeObject(result);

                        connection.Publish(args.Message.Reply, bytes);
                    }
                    catch (Exception ex)
                    {
                        _logger?.LogError(ex, "Unhandled exception during rpc-request has occured");
                    }
                };

                yield return(subscription);
            }
        }