// from MongoDB.Bson.Serialization.BsonDefaultSerializationProvider.GetCollectionSerializer() private IBsonSerializer GetCollectionSerializer(Type type) { Type implementedGenericDictionaryInterface = null; Type implementedGenericEnumerableInterface = null; Type implementedDictionaryInterface = null; Type implementedEnumerableInterface = null; var implementedInterfaces = new List <Type>(type.GetInterfaces()); if (type.IsInterface) { implementedInterfaces.Add(type); } foreach (var implementedInterface in implementedInterfaces) { if (implementedInterface.IsGenericType) { var genericInterfaceDefinition = implementedInterface.GetGenericTypeDefinition(); if (genericInterfaceDefinition == typeof(IDictionary <,>)) { implementedGenericDictionaryInterface = implementedInterface; } if (genericInterfaceDefinition == typeof(IEnumerable <>)) { implementedGenericEnumerableInterface = implementedInterface; } } else { if (implementedInterface == typeof(IDictionary)) { implementedDictionaryInterface = implementedInterface; } if (implementedInterface == typeof(IEnumerable)) { implementedEnumerableInterface = implementedInterface; } } } // the order of the tests is important if (implementedGenericDictionaryInterface != null) { var keyType = implementedGenericDictionaryInterface.GetGenericArguments()[0]; var valueType = implementedGenericDictionaryInterface.GetGenericArguments()[1]; //var genericSerializerDefinition = typeof(DictionarySerializer<,>); var genericSerializerDefinition = BsonSerializer.LookupGenericSerializerDefinition(typeof(Dictionary <,>)); if (genericSerializerDefinition == null) { //throw new PBException("error missing generic dictionary serializer"); genericSerializerDefinition = typeof(DictionarySerializer <,>); } var genericSerializerType = genericSerializerDefinition.MakeGenericType(keyType, valueType); return((IBsonSerializer)Activator.CreateInstance(genericSerializerType)); } else if (implementedDictionaryInterface != null) { IBsonSerializer serializer = BsonSerializer.LookupSerializer(typeof(IDictionary)); if (serializer != null) { return(serializer); } return(new DictionarySerializer()); } else if (implementedGenericEnumerableInterface != null) { var valueType = implementedGenericEnumerableInterface.GetGenericArguments()[0]; var readOnlyCollectionType = typeof(ReadOnlyCollection <>).MakeGenericType(valueType); Type genericSerializerDefinition; if (readOnlyCollectionType.IsAssignableFrom(type)) { //genericSerializerDefinition = typeof(ReadOnlyCollectionSerializer<>); genericSerializerDefinition = BsonSerializer.LookupGenericSerializerDefinition(typeof(ReadOnlyCollection <>)); if (genericSerializerDefinition == null) { genericSerializerDefinition = typeof(ReadOnlyCollectionSerializer <>); } if (type != readOnlyCollectionType) { BsonSerializer.RegisterDiscriminator(type, type.Name); } } else { //genericSerializerDefinition = typeof(EnumerableSerializer<>); genericSerializerDefinition = BsonSerializer.LookupGenericSerializerDefinition(typeof(IEnumerable <>)); if (genericSerializerDefinition == null) { genericSerializerDefinition = typeof(EnumerableSerializer <>); } } var genericSerializerType = genericSerializerDefinition.MakeGenericType(valueType); return((IBsonSerializer)Activator.CreateInstance(genericSerializerType)); } else if (implementedEnumerableInterface != null) { IBsonSerializer serializer = BsonSerializer.LookupSerializer(typeof(IEnumerable)); if (serializer != null) { return(serializer); } return(new EnumerableSerializer()); } return(null); }