/// <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); }
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; }
/// <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>); }
public EnumStringSerializerDecorator([NotNull] ITypeSerializerStrategy <string> stringSerializer) { if (stringSerializer == null) { throw new ArgumentNullException(nameof(stringSerializer), $"Provided argument {stringSerializer} is null."); } decoratedSerializer = stringSerializer; }
public GenericReadToEndSerializerStrategyDecorator([NotNull] ITypeSerializerStrategy <TObjectType> elementSerializer) { if (elementSerializer == null) { throw new ArgumentNullException(nameof(elementSerializer)); } ElementSerializer = elementSerializer; }
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; }
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); }
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; }
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(); }
/// <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)); }
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); }
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>); }
/// <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); }
/// <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) { }