public static Type GenerateProxy(Type type) { if (_ab == null) { var assmName = new AssemblyName("FastDeepCloner.DynamicAssembly"); _ab = AssemblyBuilder.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.Run); _mb = _ab.DefineDynamicModule(assmName.Name); } TypeBuilder typeBuilder = _mb.DefineType(type.Name + "__FastDeepClonerProxyInstance", TypeAttributes.Public, type); if (!typeof(INotifyPropertyChanged).IsAssignableFrom(type)) { typeBuilder.AddInterfaceImplementation(typeof(INotifyPropertyChanged)); } FieldBuilder eventField = CreatePropertyChangedEvent(typeBuilder); MethodBuilder raisePropertyChanged = CreateRaisePropertyChanged(typeBuilder, eventField); // get all the public or protected // virtual property setters. var props = DeepCloner.GetFastDeepClonerProperties(type).Where(x => x.CanRead && x.IsVirtual == true); props.ToList().ForEach( (item) => WrapMethod( item, raisePropertyChanged, typeBuilder)); Type ret = typeBuilder.CreateTypeInfo().AsType(); return(ret); }
internal static object ConvertToInterface(this Type interfaceType, object item) { var type = item.GetType(); if (interfaceType.IsAssignableFrom(type)) { return(item); } var props = DeepCloner.GetFastDeepClonerProperties(type); var args = new SafeValueType <string, object>(); foreach (var iProp in DeepCloner.GetFastDeepClonerProperties(interfaceType)) { var p = DeepCloner.GetProperty(type, iProp.Name); if (p == null) { continue; } var value = p.GetValue(item); if (value == null || p.PropertyType == iProp.PropertyType) { args.Add(iProp.Name, value); continue; } try { if (iProp.PropertyType.IsInterface) { args.Add(iProp.Name, iProp.PropertyType.InterFaceConverter(value)); } else { args.Add(iProp.Name, Convert.ChangeType(value, DeepCloner.GetProperty(interfaceType, p.Name).PropertyType)); } } catch (Exception e) { var iType = iProp.PropertyType; throw new Exception($"Property {p.Name} has different type then the interface which is of type {iProp.PropertyType}. \n (Convert.ChangeType) could not convert from {p.PropertyType} to {iType}. \n Orginal Exception: {e.Message}"); } } var key = $"{(type.IsAnonymousType() ? string.Join(" | ", props.Select(x => x.FullName).ToArray()) : type.FullName)} | {interfaceType.FullName}"; var newtype = CachedConvertedObjectToInterface.ContainsKey(key) ? CachedConvertedObjectToInterface[key] : CachedConvertedObjectToInterface.GetOrAdd(key, FastDeepCloner.ConvertToInterfaceTypeGenerator.Convert(interfaceType, type)); var returnValue = Creator(newtype, false, args.Values.ToArray()); var constructor = GetConstructorInfo(newtype, args.Values.ToArray()); if (constructor == null) { foreach (var p in args) { DeepCloner.GetProperty(newtype, p.Key).SetValue(returnValue, args[p.Key]); } } return(returnValue); }
public static Type Convert(Type interfaceType, Type type) { try { if (!interfaceType.IsInterface) { throw new Exception("Type need to be an interface"); } var className = interfaceType.Name + "__" + (type.IsAnonymousType() ? Guid.NewGuid().ToString("N") : type.Name) + "__FastDeepClonerConvertToInterface"; if (_ab == null) { var assmName = new AssemblyName("FastDeepCloner.DynamicAssembly.Interface"); _ab = AssemblyBuilder.DefineDynamicAssembly(assmName, AssemblyBuilderAccess.Run); _mb = _ab.DefineDynamicModule(assmName.Name); } var classType = typeof(object); TypeBuilder typeBuilder = _mb.DefineType(className, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, classType); var props = DeepCloner.GetFastDeepClonerProperties(interfaceType); CreateConstructor(props, typeBuilder, CreateProperty(props, typeBuilder)); if (!interfaceType.IsAssignableFrom(type)) { typeBuilder.AddInterfaceImplementation(interfaceType); } else { return(type); } return(typeBuilder.CreateTypeInfo().AsType()); } catch (Exception e) { throw e; } }
internal static string GetFastDeepClonerIdentifier(this object o) { if (o == null) { return(null); } var type = o.GetType(); var p = CachedFastDeepClonerIdentifier.ContainsKey(type) ? CachedFastDeepClonerIdentifier[type] : CachedFastDeepClonerIdentifier.GetOrAdd(type, DeepCloner.GetFastDeepClonerProperties(type).FirstOrDefault(x => x.FastDeepClonerPrimaryIdentifire)); return(p == null ? null : type.FullName + type.Name + p.Name + p.FullName + p.GetValue(o)); }