public void EndSetMembers(CodeGenerator generator, ArgBuilder targetObject) { generator.Ldarg(targetObject); generator.Load(null); generator.If(Cmp.EqualTo); generator.Pop(); LocalBuilder dataRow = generator.DeclareLocal(typeof(DataRow)); generator.Ldloc(locDataTable); generator.Call(typeof(DataTable).GetMethod("NewRow")); generator.Stloc(dataRow); LocalBuilder locCurrent = generator.DeclareLocal(typeof(string)); LocalBuilder locEnumerator = generator.DeclareLocal(typeof(Dictionary<string, object>.KeyCollection.Enumerator)); generator.Ldloc(locMemberValues); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Keys")); generator.Call(typeof(Dictionary<string, object>.KeyCollection).GetMethod("GetEnumerator")); generator.Stloc(locEnumerator); MethodInfo getCurrentMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("get_Current"); MethodInfo moveNextMethod = typeof(Dictionary<string, object>.KeyCollection.Enumerator).GetMethod("MoveNext"); generator.ForEach(locCurrent, typeof(string), typeof(Dictionary<string, object>.KeyCollection.Enumerator), locEnumerator, getCurrentMethod); generator.Ldloc(dataRow); generator.Ldloc(locCurrent); generator.Ldloc(locMemberValues); generator.Ldloc(locCurrent); generator.Call(typeof(Dictionary<string, object>).GetMethod("get_Item")); generator.Call(typeof(DataRow).GetMethod("set_Item", new Type[] { typeof(string), typeof(object) })); generator.EndForEach(moveNextMethod); generator.Ldloc(dataRow); generator.EndIf(); }
public void BeginSetMembers(CodeGenerator generator, ArgBuilder targetObject) { locMemberValues = generator.DeclareLocal(typeof(Dictionary<string, object>), "memberValues"); locDataTable = generator.DeclareLocal(typeof(DataTable), "dataTable"); generator.New(typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes)); generator.Stloc(locMemberValues); generator.New(typeof(DataTable).GetConstructor(Type.EmptyTypes)); generator.Stloc(locDataTable); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { LocalBuilder locValue = generator.DeclareLocal(typeof(string)); Type targetType = memberValue.LocalType; Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType); generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(NameValueCollection).GetMethod("get_Item", new Type[] { typeof(string) })); generator.Stloc(locValue); if (targetType.IsAssignableFrom(typeof(string))) { generator.Ldloc(locValue); generator.Stloc(memberValue); return; } else { generator.Ldloc(locValue); generator.Call(typeof(string).GetMethod("IsNullOrEmpty")); generator.Load(true); generator.If(Cmp.NotEqualTo); if (targetType == typeof(Guid)) { generator.Ldloc(locValue); generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) })); generator.Stloc(memberValue); } else { MethodInfo parseMethod = targetType.GetMethod("Parse", new Type[] { typeof(string) }); if (parseMethod != null) { generator.Ldloc(locValue); generator.Call(parseMethod); generator.Stloc(memberValue); } else { generator.Ldloc(locValue); generator.Load(originalType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); } } generator.Else(); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.EndIf(); } }
public override ConvertHandler GetConvertHandler(Type inputType, Type outputType, object inputObject, object outputObject, Dictionary<string, string> mappingNames, List<string> ignoreList, Dictionary<int, string> mappingOrders, bool mappingSpecifiedOnly) { Dictionary<string, string> distToSrc = new Dictionary<string, string>(); Dictionary<string, MemberInfo> members = new Dictionary<string, MemberInfo>(); foreach (string sourceName in mappingNames.Keys) { MemberInfo sourceMember = ConvertorGeneratorHelper.GetMemberInfo(inputType, sourceName); Check.Require(sourceMember != null, string.Format("member named {0} could not be found in {1}", sourceName, outputType.FullName)); distToSrc.Add(mappingNames[sourceName], sourceName); members.Add(mappingNames[sourceName], sourceMember); } if (!mappingSpecifiedOnly) { Dictionary<string, MemberInfo> sourceMembers = ConvertorGeneratorHelper.GetMembers(inputType); foreach (string sourceName in sourceMembers.Keys) { if (!ignoreList.Contains(sourceName) && !distToSrc.ContainsKey(sourceName)) { distToSrc.Add(sourceName, sourceName); members.Add(sourceName, sourceMembers[sourceName]); } } } CodeGenerator gen = new CodeGenerator(); gen.BeginMethod("m" + Guid.NewGuid().ToString("N"), typeof(ConvertHandler)); ArgBuilder inputObjectArg = new ArgBuilder(0, inputType); ArgBuilder outputObjectArg = new ArgBuilder(1, outputType); int currentCount = 0; int memberCount = members.Count; string[] keys = new string[memberCount]; distToSrc.Keys.CopyTo(keys, 0); List<string> keyList = new List<string>(keys); MemberSetterGenerator.BeginSetMembers(gen, outputObjectArg); while (currentCount < memberCount) { currentCount++; string targetName = ConvertorGeneratorHelper.GetCurrentKey(mappingOrders, currentCount, keyList).Replace("_", ""); if (string.IsNullOrEmpty(targetName)) { continue; } string sourceName = distToSrc[targetName].Replace("_",""); if (MemberGetterGenerator.ContainsMember(sourceName, inputType, inputObject) && MemberSetterGenerator.ContainsMember(targetName, outputType, outputObject)) { Type targetType = ConvertorGeneratorHelper.GetMemberType(members[targetName]); LocalBuilder memberValue = gen.DeclareLocal(targetType, "memberValue"); MemberGetterGenerator.GetMemberValue(gen, inputObjectArg, sourceName, ref memberValue); MemberSetterGenerator.SetMemberValue(gen, outputObjectArg, targetName, memberValue); } } gen.Ldarg(outputObjectArg); MemberSetterGenerator.EndSetMembers(gen, outputObjectArg); return (ConvertHandler)gen.EndMethod(); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { LocalBuilder tempLocal = generator.DeclareLocal(typeof(object), "dataColumn"); Type targetType = memberValue.LocalType; Type originalType = ConvertorGeneratorHelper.GetOriginalType(targetType); generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(string) })); generator.Stloc(tempLocal); generator.Ldloc(tempLocal); generator.LoadMember(typeof(DBNull).GetField("Value", BindingFlags.Static | BindingFlags.Public)); generator.If(Cmp.EqualTo); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.Else(); generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, targetType); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); generator.Else(); if (targetType == typeof(Guid)) { generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(string)); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); generator.New(typeof(Guid).GetConstructor(new Type[] { typeof(string) })); generator.Stloc(memberValue); } else { generator.Ldloc(tempLocal); generator.InternalILGenerator.Emit(OpCodes.Isinst, typeof(IConvertible)); generator.InternalILGenerator.Emit(OpCodes.Ldnull); generator.InternalILGenerator.Emit(OpCodes.Cgt_Un); generator.Load(true); generator.If(Cmp.EqualTo); generator.Ldloc(tempLocal); generator.Load(originalType); generator.Call(typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(Type) })); if (targetType.IsValueType) { generator.UnboxAny(targetType); } generator.Stloc(memberValue); } generator.Else(); generator.LoadDefaultValue(targetType); generator.Stloc(memberValue); generator.EndIf(); generator.EndIf(); generator.EndIf(); }
public void GetMemberValue(CodeGenerator generator, ArgBuilder targetObject, string memberName, ref LocalBuilder memberValue) { MethodInfo getMethod; bool mustBeUnBox = false; switch (Type.GetTypeCode(memberValue.LocalType)) { case TypeCode.Boolean: getMethod = typeof(IDataRecord).GetMethod("GetBoolean"); break; case TypeCode.Byte: getMethod = typeof(IDataRecord).GetMethod("GetByte"); break; case TypeCode.Char: getMethod = typeof(IDataRecord).GetMethod("GetChar"); break; case TypeCode.DateTime: getMethod = typeof(IDataRecord).GetMethod("GetDateTime"); break; case TypeCode.Decimal: getMethod = typeof(IDataRecord).GetMethod("GetDecimal"); break; //Teddy 2008-2-2: commented the lines below, because for some database, return data type of float or real could always be System.Single or System.Double //case TypeCode.Double: // getMethod = typeof(IDataRecord).GetMethod("GetDouble"); // break; //case TypeCode.Single: // getMethod = typeof(IDataRecord).GetMethod("GetFloat"); // break; case TypeCode.Int16: getMethod = typeof(IDataRecord).GetMethod("GetInt16"); break; case TypeCode.Int32: getMethod = typeof(IDataRecord).GetMethod("GetInt32"); break; case TypeCode.Int64: getMethod = typeof(IDataRecord).GetMethod("GetInt64"); break; case TypeCode.String: getMethod = typeof(IDataRecord).GetMethod("GetString"); break; default: getMethod = typeof(IDataRecord).GetMethod("GetValue"); mustBeUnBox = true; break; } if (memberValue.LocalType == typeof(Guid)) { getMethod = typeof(IDataRecord).GetMethod("GetGuid"); mustBeUnBox = false; } if (memberValue.LocalType.IsEnum) { getMethod = typeof(IDataRecord).GetMethod("GetValue"); mustBeUnBox = true; } generator.Ldarg(targetObject); generator.Load(memberName); generator.Call(typeof(IDataRecord).GetMethod("GetOrdinal")); LocalBuilder fieldOrdinalLoc = generator.DeclareLocal(typeof(int)); generator.Stloc(fieldOrdinalLoc); generator.Ldarg(targetObject); generator.Ldloc(fieldOrdinalLoc); generator.Call(typeof(IDataRecord).GetMethod("IsDBNull")); generator.IfNot(); generator.Ldarg(targetObject); generator.Ldloc(fieldOrdinalLoc); generator.Call(getMethod); //Teddy 2008-2-2: added the code section below to convert the object to the memberValue.LocalType if (!memberValue.LocalType.IsEnum && getMethod == typeof(IDataRecord).GetMethod("GetValue")) { generator.Load(Type.GetTypeCode(memberValue.LocalType)); generator.Call(typeof(Convert).GetMethod("ChangeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(object), typeof(TypeCode) }, null)); } if (memberValue.LocalType.IsValueType && mustBeUnBox) { generator.UnboxAny(memberValue.LocalType); } generator.Else(); generator.LoadDefaultValue(memberValue.LocalType); generator.EndIf(); generator.Stloc(memberValue); }