void SetupGlobalTypeMapper()
        {
            // Look for TypeHandlerFactories with mappings in our assembly, set them up
            foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => t.GetTypeInfo().IsSubclassOf(typeof(NpgsqlTypeHandlerFactory))))
            {
                var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false);
                if (!mappingAttributes.Any())
                {
                    continue;
                }

                var factory = (NpgsqlTypeHandlerFactory)Activator.CreateInstance(t);

                foreach (TypeMappingAttribute m in mappingAttributes)
                {
                    // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later.
                    AddMapping(new NpgsqlTypeMappingBuilder
                    {
                        PgTypeName         = m.PgName,
                        NpgsqlDbType       = m.NpgsqlDbType,
                        DbTypes            = m.DbTypes,
                        ClrTypes           = m.ClrTypes,
                        InferredDbType     = m.InferredDbType,
                        TypeHandlerFactory = factory,
                    }.Build());
                }
            }

            // Look for NpgsqlTypeHandler classes with mappings in our assembly, set them up with the DefaultTypeHandlerFactory.
            // This is a shortcut that allows us to not specify a factory for each and every type handler
            foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => t.GetTypeInfo().IsSubclassOf(typeof(NpgsqlTypeHandler))))
            {
                var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false);
                if (!mappingAttributes.Any())
                {
                    continue;
                }

                var factory = new DefaultTypeHandlerFactory(t);

                foreach (TypeMappingAttribute m in mappingAttributes)
                {
                    // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later.
                    AddMapping(new NpgsqlTypeMappingBuilder
                    {
                        PgTypeName         = m.PgName,
                        NpgsqlDbType       = m.NpgsqlDbType,
                        DbTypes            = m.DbTypes,
                        ClrTypes           = m.ClrTypes,
                        InferredDbType     = m.InferredDbType,
                        TypeHandlerFactory = factory
                    }.Build());
                }
            }
        }
Ejemplo n.º 2
0
        void SetupGlobalTypeMapper()
        {
            // Look for TypeHandlerFactories with mappings in our assembly, set them up
            foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => typeof(NpgsqlTypeHandlerFactory).IsAssignableFrom(t.GetTypeInfo())))
            {
                var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false);
                if (!mappingAttributes.Any())
                {
                    continue;
                }

                var factory = (NpgsqlTypeHandlerFactory)Activator.CreateInstance(t) !;

                foreach (TypeMappingAttribute m in mappingAttributes)
                {
                    // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later.
                    AddMapping(new NpgsqlTypeMappingBuilder
                    {
                        PgTypeName         = m.PgName,
                        NpgsqlDbType       = m.NpgsqlDbType,
                        DbTypes            = m.DbTypes,
                        ClrTypes           = m.ClrTypes,
                        InferredDbType     = m.InferredDbType,
                        TypeHandlerFactory = factory,
                    }.Build());
                }
            }

            // Look for NpgsqlTypeHandler classes with mappings in our assembly, set them up with the DefaultTypeHandlerFactory.
            // This is a shortcut that allows us to not specify a factory for each and every type handler
            foreach (var t in typeof(TypeMapperBase).GetTypeInfo().Assembly.GetTypes().Where(t => t.GetTypeInfo().IsSubclassOf(typeof(NpgsqlTypeHandler))))
            {
                var mappingAttributes = t.GetTypeInfo().GetCustomAttributes(typeof(TypeMappingAttribute), false);
                if (!mappingAttributes.Any())
                {
                    continue;
                }

                var factory = new DefaultTypeHandlerFactory(t);

                foreach (TypeMappingAttribute m in mappingAttributes)
                {
                    // TODO: Duplication between TypeMappingAttribute and TypeMapping. Look at this later.
                    AddMapping(new NpgsqlTypeMappingBuilder
                    {
                        PgTypeName         = m.PgName,
                        NpgsqlDbType       = m.NpgsqlDbType,
                        DbTypes            = m.DbTypes,
                        ClrTypes           = m.ClrTypes,
                        InferredDbType     = m.InferredDbType,
                        TypeHandlerFactory = factory
                    }.Build());
                }
            }

            // This is an extremely ugly hack to support ReadOnlyIPAddress, which as an internal subclass of IPAddress
            // added to .NET Core 3.0 (see https://github.com/dotnet/corefx/issues/33373)
            if (_typeToNpgsqlDbType.ContainsKey(typeof(IPAddress)) &&
                Mappings.TryGetValue("inet", out var inetMapping) &&
                typeof(IPAddress).GetNestedType("ReadOnlyIPAddress", BindingFlags.NonPublic) is Type readOnlyIpType)
            {
                _typeToNpgsqlDbType[readOnlyIpType] = _typeToNpgsqlDbType[typeof(IPAddress)];
                var augmentedClrType = new Type[inetMapping.ClrTypes.Length + 1];
                Array.Copy(inetMapping.ClrTypes, augmentedClrType, inetMapping.ClrTypes.Length);
                augmentedClrType[augmentedClrType.Length - 1] = readOnlyIpType;
                Mappings["inet"] = new NpgsqlTypeMappingBuilder
                {
                    PgTypeName         = "inet",
                    NpgsqlDbType       = inetMapping.NpgsqlDbType,
                    DbTypes            = inetMapping.DbTypes,
                    ClrTypes           = augmentedClrType,
                    InferredDbType     = inetMapping.InferredDbType,
                    TypeHandlerFactory = inetMapping.TypeHandlerFactory
                }.Build();
            }
        }