예제 #1
0
        // 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);
        }