/// <inheritdoc/> protected override void AddDerivedMemberStreamChildren() { // Get the type of this node. Type dataType = TypeResolutionHelper.GetVerifiedType(this.DataTypeName); // If this is already an auto-generated nullable, then the type we care to expand is // the value-type inside the nullable type. if (this.IsAutoGeneratedNullableMember) { dataType = dataType.GenericTypeArguments[0]; } // Determine if the current node is a reference type var isReference = this.IsAutoGeneratedNullableMember || !dataType.IsValueType || Nullable.GetUnderlyingType(dataType) != null; if (dataType != null) { // Add a child node for each public instance property that takes no parameters. foreach (PropertyInfo propertyInfo in dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(property => !property.GetMethod.GetParameters().Any())) { this.AddDerivedMemberStreamChild(propertyInfo, propertyInfo.PropertyType, isReference && propertyInfo.PropertyType.IsValueType); } // Add a child node for each public instance field foreach (FieldInfo fieldInfo in dataType.GetFields(BindingFlags.Public | BindingFlags.Instance)) { this.AddDerivedMemberStreamChild(fieldInfo, fieldInfo.FieldType, isReference && fieldInfo.FieldType.IsValueType); } } }
// called to find the correct handler for a polymorphic field internal SerializationHandler GetUntypedHandler(int handlerId, Type baseType) { // important: all code paths that could lead to the creation of a new handler need to lock. lock (this.syncRoot) { if (this.handlersById.TryGetValue(handlerId, out SerializationHandler handler)) { return(handler); } } if (this.schemasById.TryGetValue(handlerId, out TypeSchema schema)) { // do we have a type for this schema name? if (!this.knownTypes.TryGetValue(schema.Name, out Type type)) { // nothing registered, try getting a type based on the type hint type = TypeResolutionHelper.GetVerifiedType(schema.TypeName); if (type == null) { throw new SerializationException($"Failed to create a deserializer for type {schema.Name} because no type was registered for this name and the source type {schema.TypeName} could not be found. Add a reference to the assembly containing this type, or register an alternate type for this name."); } // register the type we found with schema name this.Register(type, schema.Name); } // this will create the handler if needed return(this.GetUntypedHandler(type)); } throw new SerializationException($"Could not find the appropriate derived type with serialization handler id={handlerId} when deserializing a polymorphic instance or field of type {baseType.AssemblyQualifiedName}"); }
/// <inheritdoc/> protected override bool CanExpandDerivedMemberStreams() { // If we have already expanded this node with derived member streams if (this.InternalChildren.Any(c => c is DerivedMemberStreamTreeNode)) { // Then no longer expand return(false); } // Get the node type var nodeType = TypeResolutionHelper.GetVerifiedType(this.DataTypeName); // If it's an auto-generated nullable, we need to assess whether the inner value-type (inside the nullable) // can expand the members. if (this.IsAutoGeneratedNullableMember) { nodeType = nodeType.GenericTypeArguments[0]; } if (nodeType != null) { return(nodeType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(property => !property.GetMethod.GetParameters().Any()).Any() || nodeType.GetFields(BindingFlags.Public | BindingFlags.Instance).Any()); } return(false); }
/// <summary> /// Registers a generic serializer, that is, a serializer defined for a generic type. /// The generic serializer must implement <see cref="ISerializer{T}"/>. /// </summary> /// <param name="genericSerializer">The type of generic serializer to register.</param> public void RegisterGenericSerializer(Type genericSerializer) { // var interf = genericSerializer.GetInterface("ISerializer`1"); var interf = genericSerializer.GetInterface(typeof(ISerializer <>).FullName); var serializableType = interf.GetGenericArguments()[0]; serializableType = TypeResolutionHelper.GetVerifiedType(serializableType.Namespace + "." + serializableType.Name); // FullName doesn't work here this.templates[serializableType] = genericSerializer; }
/// <summary> /// Register known types for serialization. /// </summary> public static void RegisterKnownSerializationTypes() { KnownSerializers.Default.Register <Queue <TimeSpan> >("System.Collections.Generic.Queue`1[[System.TimeSpan, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); KnownSerializers.Default.Register <Queue <int> >("System.Collections.Generic.Queue`1[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Collections, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); KnownSerializers.Default.Register <Dictionary <int, PipelineDiagnostics> >("System.Collections.Generic.Dictionary`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Psi.Diagnostics.PipelineDiagnostics, Microsoft.Psi, Version=0.7.57.2, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); KnownSerializers.Default.Register <Dictionary <int, PipelineDiagnostics.PipelineElementDiagnostics> >("System.Collections.Generic.Dictionary`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Psi.Diagnostics.PipelineDiagnostics+PipelineElementDiagnostics, Microsoft.Psi, Version=0.7.57.2, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); KnownSerializers.Default.Register <Dictionary <int, PipelineDiagnostics.ReceiverDiagnostics> >("System.Collections.Generic.Dictionary`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Psi.Diagnostics.PipelineDiagnostics+ReceiverDiagnostics, Microsoft.Psi, Version=0.7.57.2, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); KnownSerializers.Default.Register <Dictionary <int, PipelineDiagnostics.EmitterDiagnostics> >("System.Collections.Generic.Dictionary`2[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Psi.Diagnostics.PipelineDiagnostics+EmitterDiagnostics, Microsoft.Psi, Version=0.7.57.2, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); KnownSerializers.Default.Register(TypeResolutionHelper.GetVerifiedType("System.Collections.Generic.GenericEqualityComparer`1[System.Int32]"), "System.Collections.Generic.GenericEqualityComparer`1[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"); }
/// <inheritdoc/> public Type BindToType(string assemblyName, string typeName) { return(TypeResolutionHelper.GetVerifiedType($"{typeName}, {assemblyName}")); }
/// <summary> /// Create instance of stream reader (assumes ctor taking name and path. /// </summary> /// <param name="storeName">Store name.</param> /// <param name="storePath">Store path.</param> /// <param name="streamReaderTypeName">Stream reader type name.</param> /// <returns>Stream reader instance.</returns> public static IStreamReader Create(string storeName, string storePath, string streamReaderTypeName) { return(Create(storeName, storePath, TypeResolutionHelper.GetVerifiedType(streamReaderTypeName))); }