public void AddCloningModeOverrides(object source, CloningMode mode) { if (!cloningModeOverrides.Contains(source)) { cloningModeOverrides.Add(source, mode); } }
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)); } }
protected override T CloneInternal <T>(T source, CloningMode mode) { if (_cloned.TryGetValue(source, out var val)) { return((T)val); } return(CloneComplex(source, mode)); }
public T Clone <T>(T source, CloningMode mode) { if (source == null) { return(source); } return(CloneInternal(source, mode)); }
public FieldWrapper(Type type, FieldInfo fieldInfo, CloningMode cloningMode) { FieldInfo = fieldInfo; CloningMode = cloningMode; createGetValueExpression(type, fieldInfo); createSetValueExpression(type, fieldInfo); }
public PropertyWrapper(Type type, PropertyInfo propertyInfo, CloningMode cloningMode) { PropertyInfo = propertyInfo; CloningMode = cloningMode; createGetValueExpression(type, propertyInfo); createSetValueExpression(type, propertyInfo); }
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); }
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])); }
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; } }
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)); }
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())); }
/// <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); }
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)); } }
protected abstract T CloneComplex <T>(T source, CloningMode mode);
public CloneableAttribute(CloningMode mode) { Mode = mode; }
protected override T CloneInternal <T>(T source, CloningMode mode) { return(source); }
protected abstract T CloneInternal <T>(T source, CloningMode mode);
public Cloneable(CloningMode cloneMode) { this.CloneMode = cloneMode; }
//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; }