internal static Type GetIListItemType(this Type type)
 {
     if (CachedIListInternalTypes.ContainsKey(type))
     {
         return(CachedIListInternalTypes[type]);
     }
     if (type.IsArray)
     {
         CachedIListInternalTypes.TryAdd(type, type.GetElementType());
     }
     else
     {
         if (type.GenericTypeArguments.Any())
         {
             CachedIListInternalTypes.TryAdd(type, type.GenericTypeArguments.First());
         }
         else if (type.FullName.Contains("List`1") || type.FullName.Contains("ObservableCollection`1"))
         {
             CachedIListInternalTypes.TryAdd(type, type.GetRuntimeProperty("Item").PropertyType);
         }
         else
         {
             CachedIListInternalTypes.TryAdd(type, type);
         }
     }
     return(CachedIListInternalTypes[type]);
 }
        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.TryAdd(iProp.Name, value);
                    continue;
                }
                try
                {
                    if (iProp.PropertyType.IsInterface)
                    {
                        args.TryAdd(iProp.Name, iProp.PropertyType.InterFaceConverter(value));
                    }
                    else
                    {
                        args.TryAdd(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);
        }
 internal static Dictionary <string, IFastDeepClonerProperty> GetFastDeepClonerProperties(this Type primaryType)
 {
     if (!CachedPropertyInfo.ContainsKey(primaryType))
     {
         var properties = new SafeValueType <string, IFastDeepClonerProperty>();
         if (primaryType.GetTypeInfo().BaseType != null && primaryType.GetTypeInfo().BaseType.Name != "Object")
         {
             primaryType.GetRuntimeProperties().Where(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x))).ToList();
             primaryType.GetTypeInfo().BaseType.GetRuntimeProperties().Where(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x))).ToList();
         }
         else
         {
             primaryType.GetRuntimeProperties().Where(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x))).ToList();
         }
         CachedPropertyInfo.Add(primaryType, properties);
     }
     return(CachedPropertyInfo[primaryType]);
 }
        private static SafeValueType <string, IFastDeepClonerProperty> GetPropertiesInternal(Type primaryType, ICollection <PropertyInfo> ignorePropertyInfos)
        {
            var properties = new SafeValueType <string, IFastDeepClonerProperty>();

            if (primaryType.GetTypeInfo().BaseType != null && primaryType.GetTypeInfo().BaseType.Name != "Object")
            {
                primaryType.GetRuntimeProperties().Except(ignorePropertyInfos).ToList()
                .ForEach(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x)));
                primaryType.GetTypeInfo().BaseType.GetRuntimeProperties().Except(ignorePropertyInfos).ToList()
                .ForEach(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x)));
            }
            else
            {
                primaryType.GetRuntimeProperties().Except(ignorePropertyInfos).ToList()
                .ForEach(x => properties.TryAdd(x.Name, new FastDeepClonerProperty(x)));
            }

            return(properties);
        }
        internal static Type GetFastType(this string typeName, string assembly)
        {
            if (string.IsNullOrEmpty(assembly))
            {
                throw new Exception("AssemblyName cannot be empty");
            }

            if (!assembly.ToLower().EndsWith(".dll"))
            {
                assembly += ".dll";
            }
            var key = typeName + assembly;

            if (CachedStringTypes.ContainsKey(key))
            {
                return(CachedStringTypes.Get(key));
            }

            var type = Type.GetType($"{typeName}, {assembly.Substring(0, assembly.ToLower().IndexOf(".dll"))}");

            if (type != null)
            {
                if (!CachedAssembly.ContainsKey(assembly))
                {
                    CachedAssembly.TryAdd(assembly, type.Assembly);
                }
                return(CachedStringTypes.GetOrAdd(key, type));
            }
            else
            if (!CachedAssembly.ContainsKey(assembly))
            {
                CachedAssembly.TryAdd(assembly, Assembly.LoadFrom(assembly));
            }

            return(CachedStringTypes.GetOrAdd(key, CachedAssembly.Get(assembly).GetType(typeName, true, true)));
        }
        internal static INotifyPropertyChanged ProxyCreator(this Type type)
        {
            lock (ProxyTypes)
            {
                try
                {
                    MethodInfo method;
                    if (ProxyTypesPropertyChanged.ContainsKey(type))
                    {
                        method = ProxyTypesPropertyChanged[type];
                    }
                    else
                    {
                        method = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(x => x.GetParameters().Any(a => a.ParameterType == typeof(object)) && x.GetParameters().Any(a => a.ParameterType == typeof(PropertyChangedEventArgs)));
                        ProxyTypesPropertyChanged.TryAdd(type, method);
                    }
                    INotifyPropertyChanged item;
                    if (ProxyTypes.ContainsKey(type))
                    {
                        item = ProxyTypes[type].Creator() as INotifyPropertyChanged;
                    }
                    else
                    {
                        ProxyTypes.Add(type, INotifyPropertyChangedProxyTypeGenerator.GenerateProxy(type));
                        item = ProxyTypes[type].Creator() as INotifyPropertyChanged;
                    }

                    if (method != null)
                    {
                        item.PropertyChanged += (PropertyChangedEventHandler)Delegate.CreateDelegate(typeof(PropertyChangedEventHandler), item, method);
                    }



                    return(item);
                }
                catch (Exception e)
                {
                    throw e;
                }
            }
        }
Example #7
0
 public new void Add(Attribute attr)
 {
     ContainedAttributes.TryAdd(attr, attr, true);
     ContainedAttributestypes.TryAdd(attr.GetType(), attr, true);
     base.Add(attr);
 }
        internal object CloneTo(object itemToClone, object CloneToItem)
        {
            var identifier = CloneToItem.GetFastDeepClonerIdentifier();

            if (identifier != null && _alreadyCloned.ContainsKey(identifier))
            {
                return(_alreadyCloned[identifier]);
            }

            if (identifier != null)
            {
                _alreadyCloned.TryAdd(identifier, CloneToItem);
            }

            var type2  = CloneToItem.GetType();
            var props2 = FastDeepClonerCachedItems.GetFastDeepClonerProperties(type2);

            foreach (var prop2 in props2)
            {
                if (!prop2.Value.CanWrite)
                {
                    continue;
                }
                var item = itemToClone;
                var prop = item.GetType().GetProperty(prop2.Key);
                foreach (var attr in prop2.Value.GetCustomAttributes <FastDeepClonerColumn>())
                {
                    var strSplit = attr.ColumnName.Split('.');
                    for (var i = 0; i < strSplit.Length; i++)
                    {
                        var p = item.GetType().GetProperty(strSplit[i]);
                        if (p != null)
                        {
                            prop = p;

                            if (i != strSplit.Length - 1)
                            {
                                item = p.GetValue(item);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }

                if (prop != null)
                {
                    var value = prop.GetValue(item);
                    if (value == null)
                    {
                        continue;
                    }
                    if (prop.PropertyType.IsInternalType())
                    {
                        prop2.Value.SetValue(CloneToItem, FastDeepClonerCachedItems.Value(value, prop2.Value.PropertyType, true));
                    }
                    else if (prop.PropertyType == prop2.Value.PropertyType)
                    {
                        prop2.Value.SetValue(CloneToItem, value.Clone());
                    }
                    else if (prop.PropertyType.GetIListType() == prop.PropertyType && prop2.Value.PropertyType.GetIListType() == prop2.Value.PropertyType) // if not list
                    {
                        var value2 = prop2.Value.GetValue(item);
                        if (value2 == null)
                        {
                            value2 = prop2.Value.PropertyType.CreateInstance();
                        }
                        prop2.Value.SetValue(CloneToItem, CloneTo(value, value2));
                    }
                }
            }

            return(CloneToItem);
        }