private Type CreateMapType(TypeKey key) { Type toObjectType = null; if (key != null && key.FromType != null && key.ToType != null && key.FromType.IsClass && key.ToType.IsClass && key.ToType.GetConstructor(Type.EmptyTypes) != null ) { var toObjectBaseType = typeof(object); var typeBuilder = this.m_moduleBuilder.DefineType(this.GetDynamicName(key), toObjectBaseType.Attributes, toObjectBaseType, new Type[] { typeof(IToObject) }); #region ctor var baseCtor = toObjectBaseType.GetConstructor(Type.EmptyTypes); ConstructorBuilder ctor = typeBuilder.DefineConstructor(baseCtor.Attributes, baseCtor.CallingConvention, Type.EmptyTypes); ILGenerator ctorIL = ctor.GetILGenerator(); ctorIL.Emit(OpCodes.Ldarg_0); ctorIL.Emit(OpCodes.Call, baseCtor); ctorIL.Emit(OpCodes.Ret); #endregion var fromProperties = new List <PropertyInfo>(key.FromType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty)); var toProperties = new List <PropertyInfo>(key.ToType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty)); #region To(objec obj) MethodAttributes methattr = MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig; MethodBuilder toMethodBuilder = typeBuilder.DefineMethod("To", methattr, CallingConventions.Standard, typeof(object), new Type[] { typeof(object) }); ILGenerator il = toMethodBuilder.GetILGenerator(); var resultLocal = il.DeclareLocal(typeof(object)); var oLocal = il.DeclareLocal(typeof(object)); var fromLocal = il.DeclareLocal(key.FromType); var toLocal = il.DeclareLocal(key.ToType); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc, resultLocal); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc, oLocal); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Castclass, key.FromType); il.Emit(OpCodes.Stloc, fromLocal); il.Emit(OpCodes.Newobj, key.ToType.GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc, toLocal); foreach (var fp in fromProperties) { var tp = toProperties.Find(q => q.Name == fp.Name && q.PropertyType == fp.PropertyType); if (tp != null) { il.Emit(OpCodes.Ldloc, toLocal); il.Emit(OpCodes.Ldloc, fromLocal); il.Emit(OpCodes.Callvirt, fp.GetGetMethod()); il.Emit(OpCodes.Callvirt, tp.GetSetMethod()); } } il.Emit(OpCodes.Ldloc, toLocal); if (key.ToType.IsValueType) { il.Emit(OpCodes.Box, key.ToType); } il.Emit(OpCodes.Stloc, resultLocal); il.Emit(OpCodes.Ldloc, resultLocal); il.Emit(OpCodes.Ret); #endregion to2MethodBuilder end #if NETSTANDARD toObjectType = typeBuilder.CreateTypeInfo(); #else toObjectType = typeBuilder.CreateType(); #endif } return(toObjectType); }
private string GetDynamicName(TypeKey key) { return(string.Format("{0}_To_{1}_{2}", key.FromType.Name, key.ToType.Name, GetTypeId())); }