Exemple #1
0
        /// <summary>
        /// Creates a new CloneType based on a <see cref="System.Type"/>, gathering all the information that is necessary for cloning.
        /// </summary>
        /// <param name="type"></param>
        public CloneType(Type type)
        {
            this.type             = type.GetTypeInfo();
            this.copyByAssignment =
                this.type.IsDeepCopyByAssignment() ||
                typeof(MemberInfo).GetTypeInfo().IsAssignableFrom(this.type); /* Handle MemberInfo like POD */
            this.investigateOwnership = !this.copyByAssignment;
            this.surrogate            = CloneProvider.GetSurrogateFor(this.type);
            if (this.type.IsArray)
            {
                if (this.type.GetArrayRank() > 1)
                {
                    throw new NotSupportedException(
                              "Cloning multidimensional arrays is not supported in Cohee. " +
                              "Consider skipping the referring field via [CloneField] or [DontSerialize] " +
                              "attribute, or use a regular array instead.");
                }
                this.elementType = CloneProvider.GetCloneType(this.type.GetElementType());
            }

            CloneBehaviorAttribute defaultBehaviorAttrib = CloneProvider.GetCloneBehaviorAttribute(this.type);

            if (defaultBehaviorAttrib != null && defaultBehaviorAttrib.Behavior != CloneBehavior.Default)
            {
                this.behavior = defaultBehaviorAttrib.Behavior;
            }
            else
            {
                this.behavior = CloneBehavior.ChildObject;
            }
        }
Exemple #2
0
        private void PrepareCloneGraph()
        {
            // Visit the object graph in order to determine which objects to clone
            this.PrepareObjectCloneGraph(this.sourceRoot, this.targetRoot, null, CloneBehavior.ChildObject);
            this.localBehavior.Clear();

            // Determine which weak references to keep
            if (this.dropWeakReferences.Count > 0)
            {
                foreach (object source in this.targetMapping.Keys)
                {
                    this.dropWeakReferences.Remove(source);
                    if (this.dropWeakReferences.Count == 0)
                    {
                        break;
                    }
                }
            }

            // Perform late setup for surrogate objects that required it
            foreach (LateSetupEntry lateSetup in this.lateSetupSchedule)
            {
                CloneType       typeData  = GetCloneType((lateSetup.Source ?? lateSetup.Target).GetType());
                ICloneSurrogate surrogate = typeData.Surrogate;

                object lateSetupTarget = lateSetup.Target;
                surrogate.LateSetup(lateSetup.Source, ref lateSetupTarget, this);
                this.SetTargetOf(lateSetup.Source ?? lateSetup.Target, lateSetupTarget);
            }
        }
Exemple #3
0
        /// <summary>
        /// Copies the base objects data to the specified target object.
        /// </summary>
        /// <param name="baseObj"></param>
        /// <param name="targetObj"></param>
        /// <param name="fields"></param>
        public void CopyObjectTo <T>(T baseObj, T targetObj, IEnumerable <FieldInfo> fields = null)
        {
            if (fields == null)
            {
                Type objType = baseObj.GetType();
                if (!this.DoesUnwrapType(objType))
                {
                    return;
                }

                // IClonables
                if (baseObj is ICloneExplicit)
                {
                    (baseObj as ICloneExplicit).CopyDataTo(targetObj, this);
                    return;
                }

                // ISurrogate
                ICloneSurrogate surrogate = GetSurrogateFor(objType);
                if (surrogate != null)
                {
                    surrogate.RealObject = baseObj;
                    surrogate.CopyDataTo(targetObj, this);
                    return;
                }

                fields = objType.GetAllFields(ReflectionHelper.BindInstanceAll);
            }
            foreach (FieldInfo f in fields)
            {
                f.SetValue(targetObj, this.RequestObjectClone(f.GetValue(baseObj)));
            }
        }
Exemple #4
0
        /// <summary>
        /// Creates a new CloneType based on a <see cref="System.Type"/>, gathering all the information that is necessary for cloning.
        /// </summary>
        /// <param name="type"></param>
        public CloneType(Type type)
        {
            this.type = type;
            this.plainOldData =
                this.type.IsPlainOldData() ||
                typeof(MemberInfo).IsAssignableFrom(this.type); /* Handle MemberInfo like POD */
            this.investigateOwnership = !this.plainOldData;
            this.surrogate = CloneProvider.GetSurrogateFor(this.type);
            if (this.type.IsArray) this.elementType = CloneProvider.GetCloneType(this.type.GetElementType());

            CloneBehaviorAttribute defaultBehaviorAttrib = CloneProvider.GetCloneBehaviorAttribute(this.type);
            if (defaultBehaviorAttrib != null && defaultBehaviorAttrib.Behavior != CloneBehavior.Default)
                this.behavior = defaultBehaviorAttrib.Behavior;
            else
                this.behavior = CloneBehavior.ChildObject;
        }
Exemple #5
0
        private void PrepareCloneGraph()
        {
            // Visit the object graph in order to determine which objects to clone
            this.PrepareObjectCloneGraph(this.sourceRoot, this.targetRoot, null, CloneBehavior.ChildObject);
            this.localBehavior.Clear();

            // Perform late setup for surrogate objects that required it
            foreach (LateSetupEntry lateSetup in this.lateSetupSchedule)
            {
                CloneType       typeData  = GetCloneType((lateSetup.Source ?? lateSetup.Target).GetType());
                ICloneSurrogate surrogate = typeData.Surrogate;

                object lateSetupTarget = lateSetup.Target;
                surrogate.LateSetup(lateSetup.Source, ref lateSetupTarget, this);
                this.SetTargetOf(lateSetup.Source ?? lateSetup.Target, lateSetupTarget);
            }
        }
Exemple #6
0
        /// <summary>
        /// Creates a new CloneType based on a <see cref="System.Type"/>, gathering all the information that is necessary for cloning.
        /// </summary>
        /// <param name="type"></param>
        public CloneType(Type type)
        {
            this.type         = type;
            this.plainOldData =
                this.type.IsPlainOldData() ||
                typeof(MemberInfo).IsAssignableFrom(this.type);                 /* Handle MemberInfo like POD */
            this.investigateOwnership = !this.plainOldData;
            this.surrogate            = CloneProvider.GetSurrogateFor(this.type);
            if (this.type.IsArray)
            {
                this.elementType = CloneProvider.GetCloneType(this.type.GetElementType());
            }

            CloneBehaviorAttribute defaultBehaviorAttrib = CloneProvider.GetCloneBehaviorAttribute(this.type);

            if (defaultBehaviorAttrib != null && defaultBehaviorAttrib.Behavior != CloneBehavior.Default)
            {
                this.behavior = defaultBehaviorAttrib.Behavior;
            }
            else
            {
                this.behavior = CloneBehavior.ChildObject;
            }
        }
Exemple #7
0
        protected virtual object CloneObject(object baseObj)
        {
            Type objType = baseObj.GetType();

            if (!this.DoesUnwrapType(objType))
            {
                return(baseObj);
            }

            // IClonables
            if (baseObj is ICloneExplicit)
            {
                object copy = objType.CreateInstanceOf() ?? objType.CreateInstanceOf(true);
                if (objType.IsClass)
                {
                    this.RegisterObjectClone(baseObj, copy);
                }
                (baseObj as ICloneExplicit).CopyDataTo(copy, this);
                return(copy);
            }

            // ISurrogate
            ICloneSurrogate surrogate = GetSurrogateFor(objType);

            if (surrogate != null)
            {
                surrogate.RealObject = baseObj;
                object copy = surrogate.CreateTargetObject(this);
                if (objType.IsClass)
                {
                    this.RegisterObjectClone(baseObj, copy);
                }
                surrogate.CopyDataTo(copy, this);
                return(copy);
            }

            // Shallow types, cloned by assignment
            if (objType.IsDeepByValueType())
            {
                return(baseObj);
            }
            // Arrays
            else if (objType.IsArray)
            {
                Array baseArray = (Array)baseObj;
                Type  elemType  = objType.GetElementType();
                int   length    = baseArray.Length;
                Array copy      = Array.CreateInstance(elemType, length);
                this.RegisterObjectClone(baseObj, copy);

                bool unwrap = this.DoesUnwrapType(elemType);
                if (unwrap)
                {
                    for (int i = 0; i < length; ++i)
                    {
                        copy.SetValue(this.RequestObjectClone(baseArray.GetValue(i)), i);
                    }
                }
                else if (!elemType.IsValueType)
                {
                    for (int i = 0; i < length; ++i)
                    {
                        object obj = baseArray.GetValue(i);
                        copy.SetValue(this.GetRegisteredObjectClone(obj) ?? obj, i);
                    }
                }
                else
                {
                    baseArray.CopyTo(copy, 0);
                }

                return(copy);
            }
            // Reference types / complex objects
            else
            {
                object copy = objType.CreateInstanceOf() ?? objType.CreateInstanceOf(true);
                if (objType.IsClass)
                {
                    this.RegisterObjectClone(baseObj, copy);
                }

                this.CopyObjectTo(baseObj, copy, objType.GetAllFields(ReflectionHelper.BindInstanceAll));

                return(copy);
            }
        }