public CallWriter(Stream stream, Type modelInterface) { this.stream = stream; this.modelInterface = modelInterface; returnTypes = modelInterface.AllMethods().ToDictionary(x => DynamicWrapper.MethodSerialize(x), x => x.ReturnType); new Thread(ReturnReadLoop).Start(); }
public void Generate(MethodInfo method) { if (method.IsGenericMethod) { method = method.GetGenericMethodDefinition(); } var parameters = method.GetParameters(); var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray(); var methodBuilder = _wrapperBuilder.DefineMethod( method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method.ReturnType, parameterTypes); if (method.IsGenericMethod) { methodBuilder.DefineGenericParameters( method.GetGenericArguments().Select(arg => arg.Name).ToArray()); } ILGenerator ilGenerator = methodBuilder.GetILGenerator(); // Push ModelHolder onto the stack // Call ModelHolder ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Call, typeof(ModelBase).GetProperties().Where(x => x.Name == "ModelHolder").First().GetMethod); // Push the function name on the stack ilGenerator.Emit(OpCodes.Ldstr, DynamicWrapper.MethodSerialize(method)); //ilGenerator.Emit(OpCodes.Ldstr, method.Name); // Push object[] paramseters // Create object[] array ilGenerator.Emit(OpCodes.Ldc_I4_S, parameters.Length); ilGenerator.Emit(OpCodes.Newarr, typeof(object)); // Set values in array for (int i = 0; i < parameters.Length; i++) { ilGenerator.Emit(OpCodes.Dup); ilGenerator.Emit(OpCodes.Ldc_I4_S, i); Type type = parameters[i].ParameterType; ilGenerator.Emit(OpCodes.Ldarg, i + 1); if (type.IsPrimitive) { ilGenerator.Emit(OpCodes.Box, type); } //Put stack value into array position ilGenerator.Emit(OpCodes.Stelem_Ref); } var methodCall = typeof(IModelHolder).GetMethod("MethodCall"); ilGenerator.EmitCall(OpCodes.Callvirt, methodCall, new Type[] { typeof(string), typeof(object[]) }); if (method.ReturnType != typeof(void)) { if (method.ReturnType.IsPrimitive) { ilGenerator.Emit(OpCodes.Unbox_Any, method.ReturnType); } else if (method.ReturnType != typeof(object)) { ilGenerator.Emit(OpCodes.Castclass, method.ReturnType); } } else { ilGenerator.Emit(OpCodes.Pop); } ilGenerator.Emit(OpCodes.Ret); }
public CallReader(Stream stream, object instance) { this.stream = stream; this.instance = instance; methods = instance.GetType().AllMethods().Where(x => !x.IsAbstract).ToDictionary(x => DynamicWrapper.MethodSerialize(x), x => new FastMethodInfo(x)); returnTypes = instance.GetType().AllMethods().Where(x => !x.IsAbstract).ToDictionary(x => DynamicWrapper.MethodSerialize(x), x => x.ReturnType); new Thread(ReadLoop).Start(); }