示例#1
0
 public void AddCloningModeOverrides(object source, CloningMode mode)
 {
     if (!cloningModeOverrides.Contains(source))
     {
         cloningModeOverrides.Add(source, mode);
     }
 }
示例#2
0
        protected override T CloneComplex <T>(T source, CloningMode mode)
        {
            var rank = _type.GetArrayRank();

            if (rank > 1)
            {
                throw new ArgumentException("Only one-dimensional arrays are supported.", nameof(source));
            }
            var arr = source as Array;

            switch (mode)
            {
            case CloningMode.Deep:
                var elemType = _type.GetElementType();
                var newArray = Array.CreateInstance(elemType, arr.Length);
                _cloned.Add(source, newArray);
                for (var i = 0; i < arr.Length; i++)
                {
                    var value = CloneMakerFactory.GetCloneMaker(arr.GetValue(i), mode, _typeMembers, _cloned).Clone(arr.GetValue(i), mode);
                    newArray.SetValue(value, i);
                }

                return((T)(object)newArray);

            case CloningMode.Shallow:
                return((T)arr.Clone());

            default:
                throw new ArgumentException("Deep or shallow mode should be defined.", nameof(mode));
            }
        }
示例#3
0
 protected override T CloneInternal <T>(T source, CloningMode mode)
 {
     if (_cloned.TryGetValue(source, out var val))
     {
         return((T)val);
     }
     return(CloneComplex(source, mode));
 }
示例#4
0
 public T Clone <T>(T source, CloningMode mode)
 {
     if (source == null)
     {
         return(source);
     }
     return(CloneInternal(source, mode));
 }
示例#5
0
            public FieldWrapper(Type type, FieldInfo fieldInfo, CloningMode cloningMode)
            {
                FieldInfo   = fieldInfo;
                CloningMode = cloningMode;

                createGetValueExpression(type, fieldInfo);
                createSetValueExpression(type, fieldInfo);
            }
示例#6
0
            public PropertyWrapper(Type type, PropertyInfo propertyInfo, CloningMode cloningMode)
            {
                PropertyInfo = propertyInfo;
                CloningMode  = cloningMode;

                createGetValueExpression(type, propertyInfo);
                createSetValueExpression(type, propertyInfo);
            }
示例#7
0
        public override int GetHashCode()
        {
            int hash = base.GetHashCode();

            hash = HashHelper.CombineHashCodes(hash, CloningMode.GetHashCode());
            hash = HashHelper.CombineHashCodes(hash, DeletingMode.GetHashCode());
            hash = HashHelper.CombineHashCodes(hash, UpdatingMode.GetHashCode());

            return(hash);
        }
示例#8
0
        protected override T CloneComplex <T>(T source, CloningMode mode)
        {
            if (!_typeMembers.ContainsKey(_type))
            {
                var fields     = _type.GetFields(BindingFlags.Instance | BindingFlags.Public).Where(p => (p.Attributes & FieldAttributes.InitOnly) == 0).ToList();
                var properties = _type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(p => p.CanRead && p.CanWrite).ToList();
                _typeMembers.Add(_type, GetCloneMode(((IEnumerable <MemberInfo>)fields).Concat(properties)).ToList());
            }

            return(CloneWithMembers(source, _typeMembers[_type]));
        }
示例#9
0
        protected override T CloneComplex <T>(T source, CloningMode mode)
        {
            var addMethod     = _type.GetMethod(AddMethod, BindingFlags.Instance | BindingFlags.Public);
            var collection    = source as IEnumerable;
            var newCollection = (ICollection)Activator.CreateInstance(_type);

            _cloned.Add(source, newCollection);
            foreach (var item in collection)
            {
                var value = CloneMakerFactory.GetCloneMaker(item, mode, _typeMembers, _cloned).Clone(item, mode);
                addMethod.Invoke(newCollection, new object[] { value });
            }
            return((T)newCollection);
        }
        public CloneableAttribute(CloningMode type)
        {
            switch (type)
            {
            case CloningMode.Ignore:
                Mode = CloningMode.Ignore;
                break;

            case CloningMode.Shallow:
                Mode = CloningMode.Shallow;
                break;

            case CloningMode.Deep:
                Mode = CloningMode.Deep;
                break;
            }
        }
示例#11
0
        protected override T CloneInternal <T>(T source, CloningMode mode)
        {
            if (source is string str)
            {
                switch (mode)
                {
                case CloningMode.Deep:
                    return((T)(object)string.Copy(str));

                case CloningMode.Shallow:
                    return(source);

                default:
                    throw new ArgumentException("Deep or shallow mode should be defined.", nameof(mode));
                }
            }
            throw new ArgumentException("Parameter should be string", nameof(source));
        }
示例#12
0
        public object CloneObject(object source, CloningMode mode)
        {
            if (source == null)
            {
                return(null);
            }
            var modeOverride = cloningModeOverrides[source];

            if (modeOverride != null)
            {
                mode = (CloningMode)modeOverride;
            }
            var type = source.GetType();

            if (mode == CloningMode.Ignore)
            {
                return(GetDefaultValue(type));
            }
            if (type.IsValueType && (type.IsPrimitive || type.IsEnum))
            {
                return(source);
            }
            var clonedRef = GetClonedObjReference(source);

            if (clonedRef != null)
            {
                return(clonedRef);
            }
            if (mode == CloningMode.Shallow)
            {
                return(source);
            }
            foreach (var p in cloners)
            {
                if (p.CanClone(source))
                {
                    return(p.DeepClone(source, this));
                }
            }
            throw new Exception(string.Format("No Cloner exists for object: {0}, type: {1}", source, source.GetType()));
        }
示例#13
0
        /// <summary>
        /// Perform cloning of entity by calling spcified definitions
        /// </summary>
        /// <param name="unitOfWork">Unit of work instance for creating requests to DB</param>
        /// <param name="entity">Instance of entity which will be cloned</param>
        /// <param name="beforeAddAction">Optional additional action which can be called before entity is added to db set</param>
        /// <param name="cloningMode"></param>
        /// <returns>Copy of entity</returns>
        public TEntity PerformCloning(ITranslationUnitOfWork unitOfWork, TEntity entity, Action <TEntity> beforeAddAction = null, CloningMode cloningMode = CloningMode.Cloning)
        {
            this.cloningMode = cloningMode;
            if (entity == null)
            {
                return(null);
            }
            this.unitOfWork = unitOfWork;
            if (this.entitySet == null)
            {
                this.entitySet = unitOfWork.GetSet <TEntity>();
            }

            source = entity;
            if (cloningMode == CloningMode.Cloning)
            {
                target = Activator.CreateInstance <TEntity>();
                BaseTranslator.TranslateWithExceptions(entity, target, foreignKeys.Select(i => i.Name));
                entityPropsDefs.PrimaryKeysDefinition.Where(i => !i.IsPrimaryAndForeign && i.Type == typeof(Guid)).ForEach(i =>
                {
                    target.SetPropertyValue(i.Name, Guid.NewGuid());
                });
            }
            CloningDefinition();
            if (cloningMode == CloningMode.Cloning)
            {
                TranslateProperties(entity, target, foreignKeys.Select(i => i.Name).Except(affectedForeignKeys));
                beforeAddAction?.Invoke(target);
                this.entitySet.Add(target);
            }
            if (cloningMode == CloningMode.Cloning || cloningMode == CloningMode.TreeCreating)
            {
                unitOfWork.TranslationCloneCache.AddToCachedSet(source, target);
            }
            if (cloningMode == CloningMode.Deleting)
            {
                this.entitySet.Remove(source);
            }
            return(target);
        }
示例#14
0
        public static ICloneMaker GetCloneMaker <T>(T source, CloningMode mode, Dictionary <Type, IReadOnlyCollection <Tuple <MemberInfo, MemberTypes, CloningMode> > > typeMembers,
                                                    Dictionary <Object, Object> cloned)
        {
            var type = source.GetType();

            if (_typeMakers.TryGetValue(type, out var maker))
            {
                return(maker);
            }

            if (simpleTypes.Contains(type))
            {
                return(new DefaultCloneMaker());
            }
            if (source is string str)
            {
                return(new StringCloneMaker());
            }
            if (type.IsArray)
            {
                return(new ArrayCloneMaker(type, typeMembers, cloned));
            }
            if (type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollection <>)))
            {
                return(new CollectionCloneMaker(type, typeMembers, cloned));
            }

            switch (mode)
            {
            case CloningMode.Deep:
                return(new DeepCloneMaker(type, typeMembers, cloned));

            case CloningMode.Shallow:
                return(new DefaultCloneMaker());

            default:
                throw new ArgumentException("Deep or shallow mode should be defined.", nameof(mode));
            }
        }
示例#15
0
 protected abstract T CloneComplex <T>(T source, CloningMode mode);
示例#16
0
 public CloneableAttribute(CloningMode mode)
 {
     Mode = mode;
 }
示例#17
0
 protected override T CloneInternal <T>(T source, CloningMode mode)
 {
     return(source);
 }
示例#18
0
 protected abstract T CloneInternal <T>(T source, CloningMode mode);
示例#19
0
 public Cloneable(CloningMode cloneMode)
 {
     this.CloneMode = cloneMode;
 }
示例#20
0
        //public T Clone<T>(T source)
        //{

        //    return Clone(source, new Dictionary<object, object>());
        //}
        public T Clone <T>(T source)
        {
            Type type = source.GetType();

            if (type.IsPrimitive || type.IsEnum || type == typeof(string))
            {
                return(source);
            }

            if (memo.ContainsKey(source))
            {
                return((T)memo[source]);
            }

            if (type.IsArray)
            {
                Type  typeElement = Type.GetType(type.FullName.Substring(0, type.FullName.Length - 2));
                var   array       = source as Array;
                Array copiedArray = Array.CreateInstance(typeElement, array.Length);
                memo[source] = copiedArray;
                for (int i = 0; i < array.Length; i++)
                {
                    copiedArray.SetValue(Clone(array.GetValue(i)), i);
                }
            }
            else if (type.IsClass || type.IsValueType)
            {
                if (source is ICollection && type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection <>)))
                {
                    var collectionClone = Activator.CreateInstance(type.GetGenericTypeDefinition().MakeGenericType(type.GetGenericArguments()));
                    memo[source] = collectionClone;

                    var method = collectionClone.GetType().GetMethod("Add");

                    foreach (var item in source as ICollection)
                    {
                        method.Invoke(collectionClone, new[] { Clone(item) });
                    }
                }
                else
                {
                    object clone = Activator.CreateInstance(type);
                    memo[source] = clone;

                    // Copy fields
                    FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
                    foreach (FieldInfo field in fields)
                    {
                        CloningMode cloningMode = field.IsDefined(typeof(Cloneable)) ? (field.GetCustomAttribute <Cloneable>()).CloneMode : CloningMode.Deep;
                        if (cloningMode == CloningMode.Ignore)
                        {
                            continue;
                        }

                        object fieldValue = field.GetValue(source);
                        if (fieldValue != null)
                        {
                            field.SetValue(clone, cloningMode == CloningMode.Deep ? Clone(fieldValue) : fieldValue);
                        }
                    }

                    // Copy properties
                    var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite);
                    foreach (PropertyInfo property in properties)
                    {
                        CloningMode cloningMode = property.IsDefined(typeof(Cloneable)) ? (property.GetCustomAttribute <Cloneable>()).CloneMode : CloningMode.Deep;
                        if (cloningMode == CloningMode.Ignore)
                        {
                            continue;
                        }

                        object propertyValue = property.GetValue(source);
                        if (propertyValue != null)
                        {
                            property.SetValue(clone, cloningMode == CloningMode.Deep ? Clone(propertyValue) : propertyValue);
                        }
                    }
                }
            }
            return((T)memo[source]);
        }
 public CloneableAttribute()
 {
     Mode = CloningMode.Deep;
 }