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(); }
void BeginMethod(CodeGenerator ilg, string methodName, Type delegateType, bool allowPrivateMemberAccess) { #if USE_REFEMIT ilg.BeginMethod(methodName, delegateType, allowPrivateMemberAccess); #else MethodInfo signature = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = signature.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) paramTypes[i] = parameters[i].ParameterType; DynamicMethod dynamicMethod = new DynamicMethod(methodName, signature.ReturnType, paramTypes, typeof(JsonFormatWriterGenerator).Module, allowPrivateMemberAccess); ilg.BeginMethod(dynamicMethod, delegateType, methodName, paramTypes, allowPrivateMemberAccess); #endif }
/// <summary> /// Do Get Static Field Set Delegate /// </summary> /// <param name="targetModule"></param> /// <param name="fieldInfo"></param> /// <returns></returns> protected static StaticDynamicMethodProxyHandler DoGetStaticFieldSetDelegate( Module targetModule, FieldInfo fieldInfo ) { Check.Require(targetModule, "targetModule"); Check.Require(fieldInfo, "fieldInfo"); Check.Require(fieldInfo.IsStatic, "fieldInfo MUST be static here."); CodeGenerator gen = new CodeGenerator(targetModule); gen.BeginMethod("dm" + Guid.NewGuid().ToString("N"), typeof(StaticDynamicMethodProxyHandler)); gen.Ldarg(0); gen.Ldc(0); gen.Ldelem(typeof(object)); if (fieldInfo.FieldType.IsValueType) gen.UnboxAny(fieldInfo.FieldType); gen.StoreMember(fieldInfo); gen.Load(null); return (StaticDynamicMethodProxyHandler)gen.EndMethod(); }
/// <summary> /// Do GetStaticMethodDelegate /// </summary> /// <param name="targetModule"></param> /// <param name="genericMethodInfo"></param> /// <param name="genericParameterTypes"></param> /// <returns></returns> protected static StaticDynamicMethodProxyHandler DoGetStaticMethodDelegate( Module targetModule, MethodInfo genericMethodInfo, params Type[] genericParameterTypes) { #region Check preconditions Check.Require(targetModule, "targetModule"); Check.Require(genericMethodInfo, "genericMethodInfo"); Check.Require((genericParameterTypes == null && genericMethodInfo.GetGenericArguments().Length == 0) || genericParameterTypes.Length == genericMethodInfo.GetGenericArguments().Length, "The number of generic type parameter of genericMethodInfo and the input types must equal!"); Check.Require(genericMethodInfo.IsStatic, "genericMethodInfo must be static here!"); #endregion //Create a dynamic method proxy delegate used to call the specified methodinfo CodeGenerator gen = new CodeGenerator(targetModule); gen.BeginMethod("dm" + Guid.NewGuid().ToString("N"), typeof(StaticDynamicMethodProxyHandler)); MethodInfo makeGenericMethodInfo = MakeMethodGeneric(genericMethodInfo, genericParameterTypes); LoadParameters(gen, makeGenericMethodInfo.GetParameters(), true); gen.Call(makeGenericMethodInfo); CastValueToObject(gen, makeGenericMethodInfo.ReturnType); return (StaticDynamicMethodProxyHandler)gen.EndMethod(); }
/// <summary> /// Do Get Static Field Get Delegate /// </summary> /// <param name="targetModule"></param> /// <param name="fieldInfo"></param> /// <returns></returns> protected static StaticDynamicMethodProxyHandler DoGetStaticFieldGetDelegate( Module targetModule, FieldInfo fieldInfo ) { Check.Require(targetModule, "targetModule"); Check.Require(fieldInfo, "fieldInfo"); Check.Require(fieldInfo.IsStatic, "fieldInfo MUST be static here."); CodeGenerator gen = new CodeGenerator(targetModule); gen.BeginMethod("dm" + Guid.NewGuid().ToString("N"), typeof(StaticDynamicMethodProxyHandler)); gen.LoadMember(fieldInfo); CastValueToObject(gen, fieldInfo.FieldType); return (StaticDynamicMethodProxyHandler)gen.EndMethod(); }