/// <summary> /// Registers a type and serializer for the specified contract type. /// Use this overload to deserialize data persisted before a type name change. /// </summary> /// <param name="contractName">The previous contract name of type T.</param> /// <param name="cloningFlags">Optional flags that control the cloning behavior for this type.</param> /// <typeparam name="T">The type being serialized.</typeparam> /// <typeparam name="TSerializer"> /// The corresponding type of serializer to use, which replaces any <see cref="SerializerAttribute"/> annotation. /// </typeparam> public void Register <T, TSerializer>(string contractName, CloningFlags cloningFlags = CloningFlags.None) where TSerializer : ISerializer <T>, new() { Type t = typeof(T); this.Register(t, contractName, cloningFlags); this.serializers[t] = typeof(TSerializer); }
public static T GetClone <T>(this T source, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers) { if (initializers == null) { throw new ArgumentNullException(); } return(GetClone(source, flags, initializers, new Dictionary <object, object>())); }
public static T Clone(T source, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers) { if (initializers == null) { throw new ArgumentNullException(); } return(_clone(source, flags, initializers)); }
public static T GetClone <T>(this T source, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers) { //return GetClone(source, flags, initializers); return(GetClone(source, new string[] { }, flags, initializers, null, null)); }
public static T GetClone <T>(this T source, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun) { if (initializers == null) { throw new ArgumentNullException(); } //创建实例的方法 //return CloneManager<T>.Clone(source, excludeNames, flags, initializers, createObjectFun, clonedObjects); return(GetClone(source, excludeNames, flags, initializers, createObjectFun, customResolveFun, new Dictionary <object, object>())); }
private Expression GetCloningFlagsExpression(CloningFlags cloningFlags) { var flagExpression = Expression.Convert(Expression.Constant(cloningFlags, typeof(CloningFlags)), typeof(byte)); return(Expression.Equal( Expression.And( Expression.Convert(_flags, typeof(byte)), flagExpression ), flagExpression )); }
public static Expression GetCloningFlagsExpression(CloningFlags flags, ParameterExpression parameter) { var flagExpression = Expression.Convert(Expression.Constant(flags, typeof(CloningFlags)), typeof(byte)); return(Expression.Equal( Expression.And( Expression.Convert(parameter, typeof(byte)), flagExpression ), flagExpression )); }
public static T GetClone <T>(this T source, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun, Dictionary <object, object> clonedObjects) { if (clonedObjects == null) { clonedObjects = new Dictionary <object, object>(); } //var _type = typeof(T); //var constructor = _type.GetConstructor(new Type[0]); //if (_type.IsAbstract || _type.IsInterface || (!_type.IsValueType && constructor == null)|| _type==typeof(object)) //{ // if (source == null) return default(T); // return (T)typeof(CloneFactory).GetMethod(nameof(GetCloneEx), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Instance).MakeGenericMethod(source.GetType()).Invoke(null, new object[] { source, excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects }); //} //else { return(GetCloneEx <T>(source, excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects)); } }
/// <summary> /// Registers a given type with the specified contract name. /// Use this overload to deserialize data persisted before a type name change. /// </summary> /// <param name="type">The type to use when deserializing objects with the specified contract.</param> /// <param name="contractName">The name to remap. This can be a full type name or a contract name.</param> /// <param name="cloningFlags">Optional flags that control the cloning behavior for this type.</param> public void Register(Type type, string contractName, CloningFlags cloningFlags = CloningFlags.None) { contractName = contractName ?? TypeSchema.GetContractName(type, this.runtimeVersion); if (this.knownTypes.TryGetValue(contractName, out Type existingType) && existingType != type) { throw new SerializationException($"Cannot register type {type.AssemblyQualifiedName} under the contract name {contractName} because the type {existingType.AssemblyQualifiedName} is already registered under the same name."); } if (this.cloningFlags.TryGetValue(type, out var existingFlags) || this.handlersByType.ContainsKey(type)) { // cannot re-register once type flags has been registered or handler has been created if (existingFlags != cloningFlags) { throw new SerializationException($"Cannot register type {type.AssemblyQualifiedName} with cloning flags ({cloningFlags}) because a handler for it has already been created with flags ({existingFlags})."); } } this.knownTypes[contractName] = type; this.knownNames[type] = contractName; this.cloningFlags[type] = cloningFlags; }
/// <summary> /// Registers a serializer based on type. /// Use this overload to register a custom implementation of <see cref="ISerializer{T}"/>. /// </summary> /// <typeparam name="T">The type being serialized.</typeparam> /// <typeparam name="TSerializer"> /// The corresponding type of serializer to use, which replaces any <see cref="SerializerAttribute"/> annotation. /// </typeparam> /// <param name="cloningFlags">Optional flags that control the cloning behavior for this type.</param> public void Register <T, TSerializer>(CloningFlags cloningFlags = CloningFlags.None) where TSerializer : ISerializer <T>, new() => this.Register <T, TSerializer>(null, cloningFlags);
/// <summary> /// Registers a type that the serialization system would not be able find or resolve. /// Use this overload when type T is required in a polymorphic context. /// </summary> /// <typeparam name="T">The type to serialize.</typeparam> /// <param name="cloningFlags">Optional flags that control the cloning behavior for this type.</param> /// <remarks> /// When deserializing a polymorphic field, the field's object value might have a different type than the declared (static) /// type of the field (e.g the field is declared as IEnumerable{int} and is assigned a MyCustomCollection{int}). /// Pre-registering the type allows the runtime to find it in such circumstances. /// </remarks> public void Register <T>(CloningFlags cloningFlags = CloningFlags.None) => this.Register(typeof(T), null, cloningFlags);
/// <summary> /// Registers type T with the specified contract name. /// Use this overload to deserialize data persisted before a type name change. /// </summary> /// <typeparam name="T">The type to use when deserializing objects with the specified contract.</typeparam> /// <param name="contractName">The name to remap. This can be a full type name or a contract name.</param> /// <param name="cloningFlags">Optional flags that control the cloning behavior for this type.</param> public void Register <T>(string contractName, CloningFlags cloningFlags = CloningFlags.None) => this.Register(typeof(T), contractName, cloningFlags);
public static PropertyT ExeGetClone <T, PropertyT>(T source, MemberInfo info, PropertyT propertySource, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun, Dictionary <object, object> clonedObjects) { if (propertySource == null) { return(default(PropertyT)); } //if (clonedObjects.ContainsKey(propertySource)) //{ // return (PropertyT)clonedObjects[propertySource]; //} var _excludeNames = GetExcludeName(excludeNames, info?.Name); var d = new ResolveArgs(source, typeof(T), info, propertySource, typeof(PropertyT), _excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects); customResolveFun?.Invoke(d); if (d.IsResolve) { //if (!clonedObjects.ContainsKey(propertySource)) //{ // clonedObjects.Add(propertySource, d.NewValue); //} return((PropertyT)d.NewValue); } else { var _type = typeof(PropertyT); var constructor = _type.GetConstructor(new Type[0]); if (_type.IsAbstract() || _type.IsInterface() || (!_type.IsValueType() && constructor == null)) { Helpers.GetThrowInvalidOperationExceptionExpression(_type); } return(CloneFactory.GetClone(propertySource, _excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects)); } }
public T GetClone <T>(T source, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun) { return(CloneFactory.GetClone(source, excludeNames, flags, initializers, createObjectFun, customResolveFun, this.clonedObjects)); }
internal static T Clone(T source, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Dictionary <object, object> clonedObjects) { return(_clone(source, flags, initializers, clonedObjects)); }
internal static T Clone(T source, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun, Dictionary <object, object> clonedObjects) { return(_clone(source, excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects)); }
private static T GetCloneEx <T>(this T source, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun, Dictionary <object, object> clonedObjects) { return(CloneManager <T> .Clone(source, excludeNames, flags, initializers, createObjectFun, customResolveFun, clonedObjects)); }
public static T GetClone <T>(this T source, CloningFlags flags) { return(GetClone(source, flags, CustomInitializers)); }
private void CheckFlag(CloningFlags flag, CloningFlags value, bool result = true) { Assert.AreEqual(result, (value & flag) == flag); }
internal static T GetClone <T>(this T source, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Dictionary <object, object> clonedObjects) { return(CloneManager <T> .Clone(source, flags, initializers, clonedObjects)); }
public static T Clone(T source, CloningFlags flags) { return(_clone(source, flags, _emptyCustomInitializersDictionary)); }
public ResolveArgs(object source, Type sourceType, MemberInfo info, object propertySource, Type propertySourceType, string[] excludeNames, CloningFlags flags, IDictionary <Type, Func <object, object> > initializers, Func <Type, object, object> createObjectFun, Action <ResolveArgs> customResolveFun, Dictionary <object, object> clonedObjects) { this.Source = source; this.SourceType = sourceType; this.Member = info; this.PropertySource = propertySource; this.PropertySourceType = propertySourceType; this.ExcludeNames = excludeNames; this.CloningFlags = flags; this.Initializers = initializers; this.createObjectFun = createObjectFun; this.customResolveFun = customResolveFun; this.clonedObjects = clonedObjects; }