private static PropertyMapper GenerateDelegate(Type sourceType, Type targetType) { var method = new DynamicMethod("Map_" + sourceType.FullName + "_" + targetType.FullName, null, new[] { typeof(object), typeof(object) }, true); var il = method.GetILGenerator(); var sourceProperties = Reflector.GetAllProperties(sourceType); var targetProperties = Reflector.GetAllProperties(targetType); var entityMap = MappingFactory.GetEntityMap(targetType); var matches = sourceProperties.CrossJoin(targetProperties).Where(t => (t.Item2.Name == t.Item3.Name || t.Item2.Name == MappingFactory.GetPropertyOrColumnName(t.Item3, false, entityMap, false)) && t.Item2.PropertyType == t.Item3.PropertyType && t.Item2.PropertyType.IsPublic && t.Item3.PropertyType.IsPublic //&& (t.Item3.PropertyType.IsValueType || t.Item3.PropertyType == typeof(string)) && t.Item2.CanRead && t.Item3.CanWrite); foreach (var match in matches) { il.Emit(OpCodes.Ldarg_1); il.EmitCastToReference(targetType); il.Emit(OpCodes.Ldarg_0); il.EmitCastToReference(sourceType); il.Emit(OpCodes.Callvirt, match.Item2.GetGetMethod()); il.Emit(OpCodes.Callvirt, match.Item3.GetSetMethod()); } il.Emit(OpCodes.Ret); var mapper = (PropertyMapper)method.CreateDelegate(typeof(PropertyMapper)); return(mapper); }
private static void DefineProperties(Type objectType, TypeBuilder typeBuilder, FieldInfo field, Type interfaceType, DynamicProxyType proxyType, bool ignoreMappings) { var entityMap = MappingFactory.GetEntityMap(interfaceType); foreach (var property in Reflector.GetAllProperties(interfaceType)) { // check if we can support the wrapping. var propertyName = MappingFactory.GetPropertyOrColumnName(property, ignoreMappings, entityMap, false); var objectProperty = objectType != null?objectType.GetProperty(propertyName) : null; if (objectProperty != null && ((property.CanRead && !objectProperty.CanRead) || (property.CanWrite && !objectProperty.CanWrite))) { throw new InvalidCastException("Can't cast because the property is missing or does not have the required implementation."); } // check the property types. if (objectProperty != null && objectProperty.PropertyType != property.PropertyType) { throw new InvalidCastException("Can't cast because property types do not match."); } // define the property. if (proxyType == DynamicProxyType.FullIndexer) { DefineIndexerProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap); } else if (proxyType == DynamicProxyType.SimpleIndexer && IsWrappable(property, entityMap)) { DefineIndexerProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap); } else if (proxyType == DynamicProxyType.Guard) { DefineGuardedProperty(property, typeBuilder, field, objectType, ignoreMappings, entityMap); } else if (objectProperty != null) { DefineProperty(property, typeBuilder, field, objectType, objectProperty); } else { DefineDefaultProperty(property, typeBuilder); } } }