protected SubComplexTypeSerializer([NotNull] IDeserializationPrototypeFactory <TBaseType> prototypeGenerator, [NotNull] IEnumerable <IMemberSerializationMediator <TBaseType> > serializationDirections, [NotNull] IGeneralSerializerProvider serializerProvider) : base(serializationDirections, serializerProvider) { if (prototypeGenerator == null) { throw new ArgumentNullException(nameof(prototypeGenerator)); } this.prototypeGeneratorService = prototypeGenerator; }
public SubComplexTypeWithFlagsSerializerDecorator([NotNull] IDeserializationPrototypeFactory <TBaseType> prototypeGenerator, [NotNull] IEnumerable <IMemberSerializationMediator <TBaseType> > serializationDirections, [NotNull] IGeneralSerializerProvider serializerProvider, [NotNull] IChildKeyStrategy childKeyStrategy) : base(prototypeGenerator, serializationDirections, serializerProvider) { if (prototypeGenerator == null) { throw new ArgumentNullException(nameof(prototypeGenerator)); } if (serializationDirections == null) { throw new ArgumentNullException(nameof(serializationDirections)); } if (serializerProvider == null) { throw new ArgumentNullException(nameof(serializerProvider)); } if (childKeyStrategy == null) { throw new ArgumentNullException(nameof(childKeyStrategy)); } keyStrategy = childKeyStrategy; DefaultSerializer = typeof(TBaseType).GetTypeInfo().GetCustomAttribute <DefaultChildAttribute>(false) != null ? serializerProviderService.Get(typeof(TBaseType).GetTypeInfo().GetCustomAttribute <DefaultChildAttribute>(false).ChildType) : null; //We no longer reserve 0. Sometimes type information of a child is sent as a 0 in WoW protocol. We can opt for mostly metadata market style interfaces. List <ChildKeyPair> pairs = new List <ChildKeyPair>(); foreach (WireDataContractBaseTypeByFlagsAttribute waf in typeof(TBaseType).GetTypeInfo().GetCustomAttributes <WireDataContractBaseTypeByFlagsAttribute>(false)) { if (!typeof(TBaseType).GetTypeInfo().IsAssignableFrom(waf.ChildType.GetTypeInfo())) { throw new InvalidOperationException($"Failed to register Type: {typeof(TBaseType).GetType().FullName} because a provided ChildType: {waf.ChildType.FullName} was not actually a child."); } //TODO: Maybe add a priority system for flags that may override others? pairs.Add(new ChildKeyPair(waf.Flag, serializerProviderService.Get(waf.ChildType))); } serializers = pairs.ToArray(); }
public ComplexTypeSerializerDecorator([NotNull] IEnumerable <IMemberSerializationMediator <TComplexType> > serializationDirections, [NotNull] IDeserializationPrototypeFactory <TComplexType> prototypeGenerator, [NotNull] IGeneralSerializerProvider serializerProvider) //todo: create a better way to provide serialization instructions : base(serializationDirections, serializerProvider) { if (prototypeGenerator == null) { throw new ArgumentNullException(nameof(prototypeGenerator)); } //We no longer require registered types to be classes //if(!typeof(TComplexType).GetTypeInfo().IsClass) // throw new ArgumentException($"Provided generic Type: {typeof(TComplexType).FullName} must be a erence type.", nameof(TComplexType)); prototypeGeneratorService = prototypeGenerator; //This serializer is the finally link the chain when it comes to polymorphic serialization //Theore it must deal with deserialization of all members by dispatching from top to bottom (this serializer) to read the members //to do so efficiently we must cache an array of the Type that represents the linear class hierarchy reversed List <Type> typeHierarchy = ComputeTypeHierarchy(typeof(TComplexType).GetTypeInfo(), typeof(object)); //reverse the collection to the proper order typeHierarchy.Reverse(); reversedInheritanceHierarchy = typeHierarchy; }
public SubComplexTypeSerializerDecorator([NotNull] IDeserializationPrototypeFactory <TBaseType> prototypeGenerator, [NotNull] IEnumerable <IMemberSerializationMediator <TBaseType> > serializationDirections, [NotNull] IGeneralSerializerProvider serializerProvider, [NotNull] IChildKeyStrategy childKeyStrategy) : base(prototypeGenerator, serializationDirections, serializerProvider) { if (childKeyStrategy == null) { throw new ArgumentNullException(nameof(childKeyStrategy), $"Provided {nameof(IChildKeyStrategy)} used for key read and write is null."); } keyStrategy = childKeyStrategy; typeToKeyLookup = new Dictionary <Type, int>(); keyToTypeLookup = new Dictionary <int, Type>(); DefaultSerializer = typeof(TBaseType).GetTypeInfo().GetCustomAttribute <DefaultChildAttribute>(false) != null ? serializerProviderService.Get(typeof(TBaseType).GetTypeInfo().GetCustomAttribute <DefaultChildAttribute>(false).ChildType) : null; //We no longer reserve 0. Sometimes type information of a child is sent as a 0 in WoW protocol. We can opt for mostly metadata marker style interfaces. //TODO: Add support for basetype serialization metadata marking. foreach (WireDataContractBaseTypeAttribute wa in typeof(TBaseType).GetTypeInfo().GetCustomAttributes <WireDataContractBaseTypeAttribute>(false)) { if (wa.Index == keyStrategy.DefaultKey) { throw new InvalidOperationException($"Encountered reserved BaseType Key: {wa.Index} on Type: {wa.ChildType.Name}. This key value is reserved for internal handling."); } RegisterPair(wa.ChildType, wa.Index); } //If we're not abstract we may be asked to serialize ourselves if (!typeof(TBaseType).GetTypeInfo().IsAbstract) { InternallyManagedComplexSerializer = new ComplexTypeSerializerDecorator <TBaseType>(serializationDirections, prototypeGenerator, serializerProvider); } }