Example #1
0
        /// <inheritdoc />
        public override async Task WriteAsync(TBaseType value, IWireStreamWriterStrategyAsync dest)
        {
            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            Type childType = value.GetType();

            //If the actual type is just this type then we should handle serialization as if we
            //were a regular complex type
            if (childType == typeof(TBaseType))
            {
                //We know the complex serializer won't be null because it HAS to be non-abstract for this to
                //have been true
                keyStrategy.WriteDefault(dest);
                await InternallyManagedComplexSerializer.WriteAsync(value, dest)
                .ConfigureAwait(false);

                return;
            }

            ITypeSerializerStrategy serializer = GetWriteSerializer(value, ref childType);

            //TODO: Oh man, this is a disaster. How do we handle the default? How do we tell consumers to use the default?
            //Defer key writing to the key writing strategy
            await keyStrategy.WriteAsync(typeToKeyLookup[childType], dest)
            .ConfigureAwait(false);

            await serializer.WriteAsync(value, dest)
            .ConfigureAwait(false);
        }
Example #2
0
        public ITypeSerializerStrategy <TType> Create <TType>([NotNull] ISerializableTypeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (!CanHandle(context))
            {
                throw new InvalidOperationException($"Cannot handle Type: {context.TargetType.Name} with a {this.GetType().FullName}.");
            }

            if (!context.BuiltContextKey.HasValue)
            {
                throw new InvalidOperationException($"Failed to build a {nameof(ContextualSerializerLookupKey)} for the Type: {context.TargetType} with Context: {context.ToString()}.");
            }

            ITypeSerializerStrategy <TType> serializer = TryCreateSerializer <TType>(context);

            if (serializer == null)
            {
                throw new InvalidOperationException($"Failed to generate a serializer for Type: {context.TargetType.Name} with decorator factory {this.GetType().FullName}.");
            }

            return(serializer);
        }
        public EnumSerializerDecorator([NotNull] IGeneralSerializerProvider serializerProvider)
        {
            if (!typeof(TEnumType).GetTypeInfo().IsEnum)
            {
                throw new InvalidOperationException($"Cannot create an enum decorator for type {typeof(TEnumType).FullName} because it is not an enum.");
            }

            if (typeof(TEnumType).GetTypeInfo().GetEnumUnderlyingType() != typeof(TBaseType))
            {
                throw new InvalidOperationException($"Defining an Enum decorator requires {nameof(TEnumType)}'s base enum type to match {nameof(TBaseType)}.");
            }

            if (serializerProvider == null)
            {
                throw new ArgumentNullException(nameof(serializerProvider), $"Provided service {nameof(IGeneralSerializerProvider)} was null.");
            }

            try
            {
                serializerStrategy = serializerProvider.Get <TBaseType>();
            }
            catch (InvalidOperationException e)
            {
                throw new InvalidOperationException($"Failed to create strategy for Type: {typeof(TBaseType).FullName} for enum decorator for enum Type: {typeof(TEnumType).FullName}", e);
            }
        }
        public GenericChildKeyStrategy(InformationHandlingFlags typeHandling, [NotNull] ITypeSerializerStrategy <TKeyType> keyTypeSerializerStrategy)
        {
            if (keyTypeSerializerStrategy == null)
            {
                throw new ArgumentNullException(nameof(keyTypeSerializerStrategy));
            }

            int i;

            if (!Enum.IsDefined(typeof(InformationHandlingFlags), typeHandling) && Int32.TryParse(typeHandling.ToString(), out i))
            {
                throw new ArgumentOutOfRangeException(nameof(typeHandling), "Value should be defined in the InformationHandlingFlags enum.");
            }

            /*int i;
             *
             * if (!Enum.IsDefined(typeof(InformationHandlingFlags), typeHandling) && Int32.TryParse(typeHandling.ToString(), out i))
             *      throw new InvalidEnumArgumentException(nameof(typeHandling), (int)typeHandling,
             *              typeof(InformationHandlingFlags));*/

            //Try to get the max value for this type
            DefaultKey = GenericMath.Convert <TKeyType, int>(GenericMath.Convert <int, TKeyType>(Int32.MaxValue));

            typeHandlingFlags         = typeHandling;
            KeyTypeSerializerStrategy = keyTypeSerializerStrategy;
        }
Example #5
0
        /// <inheritdoc />
        public bool RegisterType(Type type, ITypeSerializerStrategy strategy)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type), $"Provided argument {nameof(type)} is null.");
            }

            if (strategy == null)
            {
                throw new ArgumentNullException(nameof(strategy), $"Provided argument {nameof(strategy)} is null.");
            }

            //Already have one
            if (this.HasSerializerFor(type))
            {
                return(true);
            }

            //This is a contextless serializer. We should register it as contextless to save perf
            //Though we should check if that is ture.
            if (strategy.ContextRequirement != SerializationContextRequirement.Contextless)
            {
                throw new InvalidOperationException($"Provided serializer Type: {strategy.GetType().FullName} is not a contextless serializer. Cannot register without context.");
            }

            //Register a new contextless serializer
            contextlessSerializerLookupTable.Add(type, strategy);

            return(true);
        }
        /// <inheritdoc />
        protected override ITypeSerializerStrategy <TType> TryCreateSerializer <TType>(ISerializableTypeContext context)
        {
            if (!context.HasContextualKey())
            {
                throw new InvalidOperationException($"No contextual key was built for Type: {context.TargetType} in {GetType().FullName}");
            }

            if (!CanHandle(context))
            {
                throw new InvalidOperationException($"Cannot create serializer for Type: {context.TargetType} and Context: {context?.BuiltContextKey?.ToString()}");
            }

            //The only type of context available to decorate primitive types with
            //is ReverseData for now
            ITypeSerializerStrategy <TType> serializer = null;

            if (serializerProviderService.HasSerializerFor <TType>())
            {
                serializer = serializerProviderService.Get <TType>();
            }

            if (context.BuiltContextKey.Value.ContextFlags.HasFlag(ContextTypeFlags.Reverse))
            {
                serializer = new EndianReverseDecorator <TType>(serializer);
            }

            return(serializer);
        }
        protected override ITypeSerializerStrategy <TType> TryCreateSerializer <TType>(ISerializableTypeContext context)
        {
            //If they want an enum string then we need to produce an string serializer
            if (context.BuiltContextKey.Value.ContextFlags.HasFlag(ContextTypeFlags.EnumString))
            {
                ContextualSerializerLookupKey stringKey = new ContextualSerializerLookupKey(context.BuiltContextKey.Value.ContextFlags, context.BuiltContextKey.Value.ContextSpecificKey, typeof(string));

                ITypeSerializerStrategy <string> serializer = null;

                if (serializerProviderService.HasSerializerFor(stringKey))
                {
                    serializer = this.serializerProviderService.Get(stringKey)
                                 as ITypeSerializerStrategy <string>;
                }
                else
                {
                    serializer = fallbackFactoryService.Create <string>(context.Override(typeof(string)).Override(stringKey));                    //override the type and key
                }
                //Now we can decorate
                return(Activator.CreateInstance(typeof(EnumStringSerializerDecorator <>).MakeGenericType(context.TargetType), serializer)
                       as ITypeSerializerStrategy <TType>);
            }

            //error handling in base
            return(Activator.CreateInstance(typeof(EnumSerializerDecorator <,>).MakeGenericType(context.TargetType, context.TargetType.GetTypeInfo().GetEnumUnderlyingType()), serializerProviderService)
                   as ITypeSerializerStrategy <TType>);
        }
Example #8
0
        public EnumStringSerializerDecorator([NotNull] ITypeSerializerStrategy <string> stringSerializer)
        {
            if (stringSerializer == null)
            {
                throw new ArgumentNullException(nameof(stringSerializer), $"Provided argument {stringSerializer} is null.");
            }

            decoratedSerializer = stringSerializer;
        }
Example #9
0
        public GenericReadToEndSerializerStrategyDecorator([NotNull] ITypeSerializerStrategy <TObjectType> elementSerializer)
        {
            if (elementSerializer == null)
            {
                throw new ArgumentNullException(nameof(elementSerializer));
            }

            ElementSerializer = elementSerializer;
        }
Example #10
0
        public EndianReverseDecorator([NotNull] ITypeSerializerStrategy <TType> serializerStrategy)
        {
            if (serializerStrategy == null)
            {
                throw new ArgumentNullException(nameof(serializerStrategy));
            }

            SerializerStrategy = serializerStrategy;
        }
        public PackedDateTimeSerializerStrategyDecorator([NotNull] ITypeSerializerStrategy <int> intSerializer)
        {
            if (intSerializer == null)
            {
                throw new ArgumentNullException(nameof(intSerializer), $"Provided arg {intSerializer} is null.");
            }

            decoratedSerializer = intSerializer;
        }
Example #12
0
        public IMemberSerializationMediator <TContainingType> Create <TContainingType>(MemberInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }

            ITypeSerializerStrategy strategy = typeSerializerProvider.Get(lookupKeyFactory.Create(info));
            //Construct a default and then we can decorate as needed
            //We now have a generic arg for the member type which we don't technically have a compile time ref to
            //therefore we must use activator to create
            IMemberSerializationMediator <TContainingType> mediator =
                Activator.CreateInstance(typeof(DefaultMemberSerializationMediator <,>).MakeGenericType(new Type[] { typeof(TContainingType), info.Type() }),
                                         info, strategy) as IMemberSerializationMediator <TContainingType>;

            //TODO: Do checking and exceptions for mediator failure

            //Check for seperated collection size attributes. We need to decorate for each one this is linked to
            foreach (var attri in info.DeclaringType.GetTypeInfo().GetCustomAttributes <SeperatedCollectionSizeAttribute>(false))
            {
                //[NotNull] MemberInfo sizeMemberInfo, [NotNull] MemberInfo collectionMemberInfo, [NotNull] ITypeSerializerStrategy serializer, [NotNull] IMemberSerializationMediator<TContainingType> decoratedMediator)
                if (attri.SizePropertyName == info.Name)
                {
                    MemberInfo collectionMember = info.DeclaringType.GetTypeInfo().GetMember(attri.CollectionPropertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).First();

                    mediator = Activator.CreateInstance(typeof(ConnectedCollectionSizeSerializationMediator <,>).MakeGenericType(new Type[] { typeof(TContainingType), info.Type() }),
                                                        info, collectionMember, strategy, mediator) as IMemberSerializationMediator <TContainingType>;
                }

                //TODO: Undefined behavior if we have to decorate this multiple times
                if (attri.CollectionPropertyName == info.Name)
                {
                    MemberInfo sizeMember = info.DeclaringType.GetTypeInfo().GetMember(attri.SizePropertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).First();

                    mediator = Activator.CreateInstance(typeof(ConnectedCollectionCollectionSerializationMediator <, ,>).MakeGenericType(new Type[] { typeof(TContainingType), sizeMember.Type(), info.Type() }),
                                                        info, sizeMember, strategy, mediator) as IMemberSerializationMediator <TContainingType>;
                }
            }

            if (info.HasAttribute <DontWriteAttribute>())
            {
                mediator = new DisableWriteMemberSerializationMediatorDecorator <TContainingType>(mediator);
            }

            if (info.HasAttribute <DontReadAttribute>())
            {
                mediator = new DisableReadMemberSerializationMediatorDecorator <TContainingType>(mediator);
            }

            if (info.HasAttribute <OptionalAttribute>())
            {
                mediator = new OptionalReadWriteMemberSerializationMediatorDecorator <TContainingType>(mediator, info.GetCustomAttribute <OptionalAttribute>().MemberName);
            }

            return(mediator);
        }
Example #13
0
        public GenericCollectionSizeStrategy([NotNull] ITypeSerializerStrategy <TSizeType> sizeTypeSerializerStrategy, sbyte addedSize)
        {
            if (sizeTypeSerializerStrategy == null)
            {
                throw new ArgumentNullException(nameof(sizeTypeSerializerStrategy));
            }

            SizeTypeSerializerStrategy = sizeTypeSerializerStrategy;
            AddedSize = addedSize;
        }
            public ChildKeyPair(int flags, [NotNull] ITypeSerializerStrategy serializer)
            {
                if (serializer == null)
                {
                    throw new ArgumentNullException(nameof(serializer));
                }

                Flags      = flags;
                Serializer = serializer;
            }
        //TODO: Refactor
        /// <inheritdoc />
        protected override ITypeSerializerStrategy <TType> TryCreateSerializer <TType>(ISerializableTypeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            IChildKeyStrategy keyStrategy = null;

            //TODO: Check if we can get this from context?
            //Check the WireDataContract attribute for keysize information
            WireDataContractAttribute contractAttribute = typeof(TType).GetTypeInfo().GetCustomAttribute <WireDataContractAttribute>(false);

            //Build the strategy for child size and value read/write
            switch (contractAttribute.OptionalChildTypeKeySize)
            {
            //TODO: Make it a factory
            case WireDataContractAttribute.KeyType.Byte:
                keyStrategy = new GenericChildKeyStrategy <byte>(contractAttribute.TypeHandling, serializerProviderService.Get <byte>());
                break;

            case WireDataContractAttribute.KeyType.Int32:
                keyStrategy = new GenericChildKeyStrategy <int>(contractAttribute.TypeHandling, serializerProviderService.Get <int>());
                break;

            case WireDataContractAttribute.KeyType.UShort:
                keyStrategy = new GenericChildKeyStrategy <ushort>(contractAttribute.TypeHandling, serializerProviderService.Get <ushort>());
                break;

            case WireDataContractAttribute.KeyType.None:
            default:
                throw new InvalidOperationException($"Encountered Type: {typeof(TType).FullName} that requires child type mapping but has provided {nameof(WireDataContractAttribute.KeyType)} Value: {contractAttribute.OptionalChildTypeKeySize} which is invalid.");
            }

            ITypeSerializerStrategy <TType> strat = null;

            //Depending on if we're flags or key return the right serializer decorator.
            if (typeof(TType).GetTypeInfo().GetCustomAttribute <WireDataContractBaseTypeByFlagsAttribute>(false) == null)
            {
                //Won't be null at this point. Should be a valid strategy. We also don't need to deal with context since there is only EVER 1 serializer of this type per type.
                strat = new SubComplexTypeSerializerDecorator <TType>(new LambdabasedDeserializationPrototyeFactory <TType>(), new MemberSerializationMediatorCollection <TType>(mediatorFactoryService).ToArray(), serializerProviderService, keyStrategy);
            }
            else
            {
                strat = new SubComplexTypeWithFlagsSerializerDecorator <TType>(new LambdabasedDeserializationPrototyeFactory <TType>(), new MemberSerializationMediatorCollection <TType>(mediatorFactoryService).ToArray(), serializerProviderService, keyStrategy);
            }

            //Check for compression flags
            if (context.BuiltContextKey.Value.ContextFlags.HasFlag(ContextTypeFlags.Compressed))
            {
                strat = new CompressionTypeSerializerStrategyDecorator <TType>(strat, serializerProviderService.Get <uint>());
            }

            return(strat);
        }
        public SizeIncludedStringSizeStrategy([NotNull] ITypeSerializerStrategy <TSizeType> serializer, bool shouldCountNullTerminator, byte addedSize)
        {
            if (serializer == null)
            {
                throw new ArgumentNullException(nameof(serializer), $"Provided argument {serializer} is null.");
            }

            sizeSerializer = serializer;

            includeNullTerminatorInSizeCalculation = shouldCountNullTerminator;
            AddedSize = addedSize;
        }
        public DontTerminateStringSerializerDecorator([NotNull] ITypeSerializerStrategy <string> stringSerializer, [NotNull] Encoding encodingStrategy)
            : base(encodingStrategy)
        {
            if (stringSerializer == null)
            {
                throw new ArgumentNullException(nameof(stringSerializer));
            }
            if (encodingStrategy == null)
            {
                throw new ArgumentNullException(nameof(encodingStrategy));
            }

            decoratedSerializer = stringSerializer;
        }
Example #18
0
        public static ITypeSerializerStrategy <TRequestedType> Get <TRequestedType>([NotNull] this IGeneralSerializerProvider provider)
        {
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            ITypeSerializerStrategy <TRequestedType> strat = provider.Get(typeof(TRequestedType)) as ITypeSerializerStrategy <TRequestedType>;

            if (strat == null)
            {
                throw new InvalidOperationException($"Unabled to locate registered Type: {typeof(TRequestedType).FullName}. Make sure to properly register the type beforing requesting a serializer.");
            }

            return(strat);
        }
        public SizeStringSerializerDecorator([NotNull] IStringSizeStrategy size, [NotNull] ITypeSerializerStrategy <string> stringSerializer, Encoding encodingStrategy)
            : base(encodingStrategy)
        {
            if (size == null)
            {
                throw new ArgumentNullException(nameof(size));
            }
            if (stringSerializer == null)
            {
                throw new ArgumentNullException(nameof(stringSerializer));
            }

            sizeProvider                  = size;
            decoratedSerializer           = stringSerializer;
            NullTermincatorCharacterArray = Enumerable.Repeat('\0', CharacterSize).ToArray();
        }
        protected MemberSerializationMediator([NotNull] MemberInfo memberInfo, [NotNull] ITypeSerializerStrategy serializer)
            : base(memberInfo, serializer)
        {
            if (memberInfo == null)
            {
                throw new ArgumentNullException(nameof(memberInfo));
            }
            if (serializer == null)
            {
                throw new ArgumentNullException(nameof(serializer));
            }

            //Due to perf problems fasterflect setting wasn't fast enough.
            //Introducing a compiled lambda to delegate for get/set should provide the much needed preformance.
            MemberSetter = new MemberSetterMediator <TContainingType, TMemberType>(memberInfo);
            MemberGetter = new MemberGetterMediator <TContainingType>(memberInfo);
            //TODO: Handle for net35. Profile fasterflect vs reflection emit
        }
        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();
        }
Example #22
0
        /// <inheritdoc />
        public override TBaseType Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Incoming should be a byte that indicates the child type to use
            //Read it to lookup in the map to determine which type we should create
            int childIndexRequested = keyStrategy.Read(source);             //defer to key reader (could be int, byte or something else)

            ITypeSerializerStrategy strategy = GetReadStrategy(childIndexRequested);

            //Once we know which child this particular object should be
            //we need to dispatch the read request to that child's serializer handler
            //and if it happens to map to another child, which should be rare, it'll dispatch until it reaches a ComplexType serializer which is where
            //the end of the inheritance graph tree should end up. The complextype serializer, which is the true type serializer, should handle deserialization
            //include going up the base heriachiry.
            return((TBaseType)strategy.Read(source));
        }
Example #23
0
 private void RegisterNewSerializerStrategy(ISerializableTypeContext context, ITypeSerializerStrategy strategy)
 {
     if (strategy.ContextRequirement == SerializationContextRequirement.Contextless)
     {
         StrategyRegistry.RegisterType(context.TargetType, strategy);
     }
     else
     {
         //TODO: Clean this up
         if (context.HasContextualKey())
         {
             //Register the serializer with the context key that was built into the serialization context.
             StrategyRegistry.RegisterType(context.BuiltContextKey.Value.ContextFlags, context.BuiltContextKey.Value.ContextSpecificKey, context.TargetType, strategy);
         }
         else
         {
             throw new InvalidOperationException($"Serializer was created but Type: {context.TargetType} came with no contextual key in the end for a contextful serialization context.");
         }
     }
 }
        //Called as the fallback factory.
        /// <inheritdoc />
        public ITypeSerializerStrategy <TType> Create <TType>([NotNull] ISerializableTypeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            //This service acts a the default/fallback factory for serializer creation. If any factory encounters a type
            //inside of a type that it doesn't know about or requires handling outside of its scope it'll broadcast that
            //and we will implement more complex handling here

            ITypeSerializerStrategy <TType> strategy = serializerStrategyFactoryService.Create <TType>(context);

            //The serializer could be null; we should verify it
            if (strategy == null)
            {
                throw new InvalidOperationException($"Failed to create serializer for Type: {context.TargetType} with Context: {context.ToString()}.");
            }

            return(strategy);
        }
Example #25
0
        private ITypeSerializerStrategy <TType> InternalCreate <TType>([NotNull] ISerializableTypeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            //TODO: Refactor this. It's duplicated code
            //We should check if the specified a custom type serializer
            if (typeof(TType).GetTypeInfo().HasAttribute <IncludeCustomTypeSerializerAttribute>())
            {
                IncludeCustomTypeSerializerAttribute attri = typeof(TType).GetTypeInfo().GetCustomAttribute <IncludeCustomTypeSerializerAttribute>();

                if (!typeof(ITypeSerializerStrategy <TType>).GetTypeInfo().IsAssignableFrom(attri.TypeSerializerType))
                {
                    throw new InvalidOperationException($"Specified custom Type Serializer Type: {attri.TypeSerializerType} but did not implement {nameof(ITypeSerializerStrategy<TType>)}. Must implment that interface for custom serializers.");
                }

                ITypeSerializerStrategy <TType> serializer = Activator.CreateInstance(attri.TypeSerializerType) as ITypeSerializerStrategy <TType>;

                this.StrategyRegistry.RegisterType(typeof(TType), serializer);

                return(serializer);
            }


            DecoratorHandler handler = decoratorHandlers.First(h => h.CanHandle(context));

            ITypeSerializerStrategy <TType> strategy = handler.Create <TType>(context);

            if (strategy == null)
            {
                throw new InvalidOperationException($"Couldn't generate a strategy for Type: {context.TargetType} with Context: {context.BuiltContextKey?.ToString()}.");
            }

            //If the serializer is contextless we can register it with the general provider
            RegisterNewSerializerStrategy(context, strategy);

            return(strategy);
        }
        private ITypeSerializerStrategy <TTypeToRegister> GetTypeSerializerStrategyForType <TTypeToRegister>()
        {
            //We should check if the specified a custom type serializer
            if (typeof(TTypeToRegister).GetTypeInfo().HasAttribute <IncludeCustomTypeSerializerAttribute>())
            {
                IncludeCustomTypeSerializerAttribute attri = typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <IncludeCustomTypeSerializerAttribute>();

                if (!typeof(ITypeSerializerStrategy <TTypeToRegister>).GetTypeInfo().IsAssignableFrom(attri.TypeSerializerType))
                {
                    throw new InvalidOperationException($"Specified custom Type Serializer Type: {attri.TypeSerializerType} but did not implement {nameof(ITypeSerializerStrategy<TTypeToRegister>)}. Must implment that interface for custom serializers.");
                }

                ITypeSerializerStrategy <TTypeToRegister> serializer = Activator.CreateInstance(attri.TypeSerializerType) as ITypeSerializerStrategy <TTypeToRegister>;

                this.serializerStorageService.RegisterType(typeof(TTypeToRegister), serializer);

                return(serializer);
            }

            //At this point this is a class marked with [WireDataContract] so we should assume and treat it as a complex type
            return(serializerStrategyFactoryService.Create <TTypeToRegister>(new TypeBasedSerializationContext(typeof(TTypeToRegister))) as ITypeSerializerStrategy <TTypeToRegister>);
        }
Example #27
0
        /// <inheritdoc />
        public override void Write(TBaseType value, IWireStreamWriterStrategy dest)
        {
            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            if (value == null)
            {
                throw new InvalidOperationException($"Serializing a null {typeof(TBaseType).FullName} is not a supported serialization scenario. It is impossible to know which type to encode.");
            }

            Type childType = value.GetType();

            //If the actual type is just this type then we should handle serialization as if we
            //were a regular complex type
            if (childType == typeof(TBaseType))
            {
                //We know the complex serializer won't be null because it HAS to be non-abstract for this to
                //have been true
                keyStrategy.WriteDefault(dest);
                InternallyManagedComplexSerializer.Write(value, dest);
                return;
            }

            ITypeSerializerStrategy serializer = GetWriteSerializer(value, ref childType);

            if (serializer == null || childType == null || !typeToKeyLookup.ContainsKey(childType))
            {
                throw new InvalidOperationException($"Unable to find serializer for Type: {typeof(TBaseType).Name} looking for Subtype: {childType.Name}");
            }

            //TODO: Oh man, this is a disaster. How do we handle the default? How do we tell consumers to use the default?
            //Defer key writing to the key writing strategy
            keyStrategy.Write(typeToKeyLookup[childType], dest);
            serializer.Write(value, dest);
        }
        /// <inheritdoc />
        public bool RegisterType <TTypeToRegister>()
        {
            //Ingoring all but wiretypes makes this a lot easier.
            if (typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractAttribute>(true) == null)
            {
                throw new InvalidOperationException($"Do not register any type that isn't marked with {nameof(WireDataContractAttribute)}. Only register WireDataContracts too; contained types will be registered automatically.");
            }

            bool result = true;

            //Check if it requires runtime linking
            if (typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractBaseLinkAttribute>(false) != null)
            {
                WireDataContractBaseLinkAttribute linkAttribute = typeof(TTypeToRegister).GetTypeInfo().GetCustomAttribute <WireDataContractBaseLinkAttribute>(false);

                //Only link if they provided a basetype.
                //Users may call RegisterType before linking so don't throw
                if (linkAttribute.BaseType != null)
                {
                    if (!serializerStorageService.HasSerializerFor(linkAttribute.BaseType))
                    {
                        RegisterType(linkAttribute.BaseType);
                    }

                    result = result && Link(linkAttribute, linkAttribute.BaseType, typeof(TTypeToRegister));
                }
            }

            if (!result)
            {
                return(false);
            }
            ITypeSerializerStrategy <TTypeToRegister> serializer = GetTypeSerializerStrategyForType <TTypeToRegister>();

            //Return the serializer; callers shouldn't need it though
            return(serializer != null && result);
        }
Example #29
0
        /// <inheritdoc />
        public bool RegisterType(ContextTypeFlags contextFlags, IContextKey key, Type type, ITypeSerializerStrategy strategy)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type), $"Provided argument {nameof(type)} is null.");
            }

            if (strategy == null)
            {
                throw new ArgumentNullException(nameof(strategy), $"Provided argument {nameof(strategy)} is null.");
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key), $"Provided argument {nameof(key)} is null.");
            }

            //Check if contextflags are none. We can skip everything and delegate to contextless
            if (contextFlags == ContextTypeFlags.None)
            {
                return(RegisterType(type, strategy));
            }

            //Register a new contextless serializer
            strategyLookupTable.Add(new ContextualSerializerLookupKey(contextFlags, key, type), strategy);

            return(true);
        }
 public DefaultMemberSerializationMediator([NotNull] MemberInfo memberInfo, [NotNull] ITypeSerializerStrategy serializer)
     : base(memberInfo, serializer)
 {
 }