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); } } }
internal static Type CreateType(Type objectType, string typeName, Type interfaceType, ModuleBuilder module, DynamicProxyType proxyType, bool ignoreMappings) { // create the type that is used to wrap the object into the interface. var typeBuilder = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout | TypeAttributes.Sealed); // add the interface implementation to the type. typeBuilder.AddInterfaceImplementation(interfaceType); if (proxyType == DynamicProxyType.Guard) { // ReSharper disable once AssignNullToNotNullAttribute typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(ReadOnlyAttribute).GetConstructor(Type.EmptyTypes), new object[] { })); } //typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(SerializableAttribute).GetConstructor(Type.EmptyTypes), new object[] { })); if (proxyType == DynamicProxyType.SimpleIndexer || proxyType == DynamicProxyType.FullIndexer) { // holds the object that is wrapped. var field = typeBuilder.DefineField("_original", objectType, FieldAttributes.Private); DefineReadOnlyProperty("Indexer", typeBuilder, field); // create the constructor for the type. DefineConstructor(objectType, typeBuilder, field); // define properties for the type DefineProperties(objectType, typeBuilder, field, interfaceType, proxyType, ignoreMappings); } else { // holds the object that is wrapped. var field = typeBuilder.DefineField("_original", objectType, FieldAttributes.Private); // create the constructor for the type. DefineConstructor(objectType, typeBuilder, field); // define properties for the type DefineProperties(objectType, typeBuilder, field, interfaceType, proxyType, false); // define some methods that are found on system.object as long as we do not create a guarded object if (proxyType != DynamicProxyType.Guard) { DefineMethod(objectType.GetMethod("ToString"), typeBuilder, field, objectType); DefineMethod(objectType.GetMethod("Equals"), typeBuilder, field, objectType); DefineMethod(objectType.GetMethod("GetType"), typeBuilder, field, objectType); DefineMethod(objectType.GetMethod("GetHashCode"), typeBuilder, field, objectType); } } // create the final type. var type = typeBuilder.CreateType(); return(type); }