85 lines
3.3 KiB
C#
85 lines
3.3 KiB
C#
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 {
|
|
/// <summary>
|
|
/// 方法调用处理器
|
|
/// </summary>
|
|
public class MethodCallHandler {
|
|
private readonly IServiceRegistry _serviceRegistry;
|
|
|
|
public MethodCallHandler(IServiceRegistry serviceRegistry) {
|
|
_serviceRegistry = serviceRegistry ?? throw new ArgumentNullException(nameof(serviceRegistry));
|
|
}
|
|
|
|
public async Task<MethodCallResponse> 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
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|