Skip to content

Commit f13c17c

Browse files
authored
Merge pull request #19 from softlgl/dev
方法调用抽离
2 parents 38cc10f + 9320430 commit f13c17c

2 files changed

Lines changed: 42 additions & 37 deletions

File tree

src/DotNetCoreRpc.Core/TaskUtils.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class TaskUtils
1717
private static readonly ConcurrentDictionary<Type, Func<object, object>> _asValueTaskFuncCache = new ConcurrentDictionary<Type, Func<object, object>>();
1818
private static readonly ConcurrentDictionary<Type, Func<object, object>> _resultFuncCache = new ConcurrentDictionary<Type, Func<object, object>>();
1919
private static readonly ConcurrentDictionary<TypeInfo, Func<object, Task>> _valueTaskAsTaskFuncCache = new ConcurrentDictionary<TypeInfo, Func<object, Task>>();
20+
private static readonly ConcurrentDictionary<MethodInfo, Func<object, object?[]?, object?>> _methodFuncCache = new ConcurrentDictionary<MethodInfo, Func<object, object?[]?, object?>>();
2021

2122
public static Func<object, object> TaskResultFunc(Type returnType)
2223
{
@@ -74,6 +75,45 @@ public static Task ValueTaskWithResultToTask(object value, TypeInfo valueTypeInf
7475
return func(value);
7576
}
7677

78+
public static Func<object, object?[]?, object?> InvokeMethod(MethodInfo methodInfo)
79+
{
80+
var methodFunc = _methodFuncCache.GetOrAdd(methodInfo, method =>
81+
{
82+
var targetParameter = Expression.Parameter(typeof(object), "target");
83+
var parametersParameter = Expression.Parameter(typeof(object?[]), "parameters");
84+
85+
var paramInfos = method.GetParameters();
86+
var parameters = new List<Expression>(paramInfos.Length);
87+
for (int i = 0; i < paramInfos.Length; i++)
88+
{
89+
var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
90+
var valueCast = Expression.Convert(valueObj, paramInfos[i].ParameterType);
91+
92+
parameters.Add(valueCast);
93+
}
94+
95+
Type targetType = method.DeclaringType;
96+
var instanceCast = Expression.Convert(targetParameter, targetType);
97+
var methodCall = Expression.Call(instanceCast, method, parameters);
98+
99+
if (methodCall.Type == typeof(void))
100+
{
101+
var lambdaAction = Expression.Lambda<Action<object, object?[]?>>(methodCall, targetParameter, parametersParameter);
102+
return (target, parameters) =>
103+
{
104+
lambdaAction.Compile().Invoke(target, parameters);
105+
return null;
106+
};
107+
}
108+
109+
var castMethodCall = Expression.Convert(methodCall, typeof(object));
110+
var lambdaFunc = Expression.Lambda<Func<object, object?[]?, object?>>(castMethodCall, targetParameter, parametersParameter);
111+
return lambdaFunc.Compile();
112+
});
113+
114+
return methodFunc;
115+
}
116+
77117
public static bool IsAsyncMethod(MethodInfo method)
78118
{
79119
bool isDefAsync = Attribute.IsDefined(method, typeof(AsyncStateMachineAttribute), false);

src/DotNetCoreRpc.Server/DotNetCoreRpcMiddleware.cs

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -129,39 +129,9 @@ private static RpcRequestDelegate PiplineEndPoint(object instance, RpcContext as
129129
{
130130
return async rpcContext =>
131131
{
132-
var targetParameter = Expression.Parameter(typeof(object), "target");
133-
var parametersParameter = Expression.Parameter(typeof(object?[]), "parameters");
134-
var paramInfos = aspectContext.Method.GetParameters();
135-
var parameters = new List<Expression>(paramInfos.Length);
136-
for (int i = 0; i < paramInfos.Length; i++)
137-
{
138-
var paramInfo = paramInfos[i];
139-
var valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i));
140-
var valueCast = Expression.Convert(valueObj, paramInfo.ParameterType);
141-
142-
// valueCast is "(Ti) parameters[i]"
143-
parameters.Add(valueCast);
144-
}
145-
var instanceCast = Expression.Convert(targetParameter, aspectContext.TargetType.GetTypeInfo().AsType());
146-
var methodCall = Expression.Call(instanceCast, aspectContext.Method, parameters);
147-
148-
Func<object, object?[]?, object?> func = null;
149-
if (methodCall.Type == typeof(void))
150-
{
151-
var lambda = Expression.Lambda<Action<object, object?[]?>>(methodCall, targetParameter, parametersParameter);
152-
func = (target, parameters) =>
153-
{
154-
lambda.Compile().Invoke(target, parameters);
155-
return null;
156-
};
157-
}
158-
else
159-
{
160-
var castMethodCall = Expression.Convert(methodCall, typeof(object));
161-
var lambda = Expression.Lambda<Func<object, object?[]?, object?>>(castMethodCall, targetParameter, parametersParameter);
162-
func = lambda.Compile();
163-
}
132+
var func = TaskUtils.InvokeMethod(aspectContext.Method);
164133
var returnValue = func.Invoke(instance, aspectContext.Parameters);
134+
165135
if (returnValue != null)
166136
{
167137
var returnValueType = returnValue.GetType().GetTypeInfo();
@@ -189,11 +159,6 @@ private static RpcRequestDelegate PiplineEndPoint(object instance, RpcContext as
189159
aspectContext.ReturnValue = TaskUtils.CreateFuncToGetTaskResult(returnValueType).Invoke(returnValue);
190160
return;
191161
}
192-
//}
193-
//if (returnValue is Task || returnValue is ValueTask)
194-
//{
195-
// return;
196-
//}
197162
}
198163
aspectContext.ReturnValue = returnValue;
199164
}

0 commit comments

Comments
 (0)