using IpcLibrary.Core; using IpcLibrary.Core.Exceptions; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace IpcLibrary.Services { /// /// 方法调用处理器 /// public class MethodCallHandler { private readonly IServiceRegistry _serviceRegistry; public MethodCallHandler(IServiceRegistry serviceRegistry) { _serviceRegistry = serviceRegistry ?? throw new ArgumentNullException(nameof(serviceRegistry)); } public async Task HandleMethodCallAsync(MethodCallRequest request) { try { var service = _serviceRegistry.GetService(request.ServiceName); if (service == null) { return new MethodCallResponse { Exception = new IPCException($"服务 '{request.ServiceName}' 未找到") }; } var serviceType = service.GetType(); MethodInfo method = null; // 查找匹配的方法 if (request.ParameterTypes != null && request.ParameterTypes.Length > 0) { method = serviceType.GetMethod(request.MethodName, request.ParameterTypes); } else { // 如果没有提供参数类型,尝试按名称和参数数量匹配 var methods = serviceType.GetMethods().Where(m => m.Name == request.MethodName); var paramCount = request.Parameters?.Length ?? 0; method = methods.FirstOrDefault(m => m.GetParameters().Length == paramCount); } if (method == null) { return new MethodCallResponse { Exception = new IPCException($"方法 '{request.MethodName}' 在服务 '{request.ServiceName}' 中未找到") }; } // 调用方法 object result; if (method.ReturnType == typeof(Task)) { // 异步方法无返回值 var task = (Task)method.Invoke(service, request.Parameters); await task; result = null; } else if (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>)) { // 异步方法有返回值 var task = (Task)method.Invoke(service, request.Parameters); await task; var resultProperty = task.GetType().GetProperty("Result"); result = resultProperty?.GetValue(task); } else { // 同步方法 result = method.Invoke(service, request.Parameters); } return new MethodCallResponse { Result = result, ResultType = method.ReturnType }; } catch (TargetInvocationException ex) { return new MethodCallResponse { Exception = ex.InnerException ?? ex }; } catch (Exception ex) { return new MethodCallResponse { Exception = ex }; } } } }