void SaveKeyBytesAndCallMethod(IILGen ilGenerator, Type relationDBManipulatorType, string methodName, ParameterInfo[] methodParameters, Type methodReturnType, IDictionary <string, MethodInfo> apartFields) { var writerLoc = ilGenerator.DeclareLocal(typeof(ByteBufferWriter)); ilGenerator.Newobj(() => new ByteBufferWriter()); ilGenerator.Stloc(writerLoc); Action <IILGen> pushWriter = il => il.Ldloc(writerLoc); //arg0 = this = manipulator if (methodName.StartsWith("RemoveById")) { CreateMethodRemoveById(ilGenerator, relationDBManipulatorType, methodName, methodParameters, methodReturnType, apartFields, pushWriter, writerLoc); } else if (methodName.StartsWith("FindById")) { CreateMethodFindById(ilGenerator, relationDBManipulatorType, methodName, methodParameters, methodReturnType, apartFields, pushWriter, writerLoc); } else if (methodName.StartsWith("FindBy")) { CreateMethodFindBy(ilGenerator, relationDBManipulatorType, methodName, methodParameters, methodReturnType, apartFields, pushWriter, writerLoc); } else if (methodName == "ListById") { CreateMethodListById(ilGenerator, relationDBManipulatorType, methodName, methodParameters, apartFields, pushWriter, writerLoc); } else if (methodName == "Contains") { CreateMethodContains(ilGenerator, relationDBManipulatorType, methodParameters, apartFields, pushWriter, writerLoc); } else { throw new NotSupportedException(); } }
public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType) { if (targetType == typeof(object)) { var resultLoc = ilGenerator.DeclareLocal(typeof(DynamicObject), "result"); var labelNoCtx = ilGenerator.DefineLabel(); ilGenerator .Do(pushDescriptor) .Castclass(typeof(ObjectTypeDescriptor)) .Newobj(typeof(DynamicObject).GetConstructor(new[] { typeof(ObjectTypeDescriptor) }) !) .Stloc(resultLoc) .Do(pushCtx) .BrfalseS(labelNoCtx) .Do(pushCtx) .Ldloc(resultLoc) .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null)) .Mark(labelNoCtx); var idx = 0; foreach (var pair in _fields) { var idxForCapture = idx; ilGenerator.Ldloc(resultLoc); ilGenerator.LdcI4(idx); pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor) .LdcI4(idxForCapture) .Callvirt(() => default(ITypeDescriptor).NestedType(0)), typeof(object), _typeSerializers.ConvertorGenerator); ilGenerator.Callvirt(() => default(DynamicObject).SetFieldByIdxFast(0, null)); idx++; } ilGenerator .Ldloc(resultLoc) .Castclass(typeof(object)); } else { var resultLoc = ilGenerator.DeclareLocal(targetType, "result"); var labelNoCtx = ilGenerator.DefineLabel(); var defaultConstructor = targetType.GetConstructor(Type.EmptyTypes); if (defaultConstructor == null) { ilGenerator .Ldtoken(targetType) .Call(() => Type.GetTypeFromHandle(new RuntimeTypeHandle())) .Call(() => RuntimeHelpers.GetUninitializedObject(null)) .Castclass(targetType); } else { ilGenerator .Newobj(defaultConstructor); } ilGenerator .Stloc(resultLoc) .Do(pushCtx) .BrfalseS(labelNoCtx) .Do(pushCtx) .Ldloc(resultLoc) .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null)) .Mark(labelNoCtx); var props = targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public); for (var idx = 0; idx < _fields.Count; idx++) { var idxForCapture = idx; var pair = _fields[idx]; var prop = props.FirstOrDefault(p => GetPersistentName(p) == pair.Key); if (prop == null || !_typeSerializers.IsSafeToLoad(prop.PropertyType)) { pair.Value.GenerateSkipEx(ilGenerator, pushReader, pushCtx); continue; } ilGenerator.Ldloc(resultLoc); pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(idxForCapture) .Callvirt(() => default(ITypeDescriptor).NestedType(0)), prop.PropertyType, _typeSerializers.ConvertorGenerator); ilGenerator.Callvirt(prop.GetAnySetMethod() !); } ilGenerator.Ldloc(resultLoc); } }