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);
        }
Exemplo n.º 3
0
        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));
        }