Major work around DbDataSource management, enum handling and plugins
- Added user-facing enum mapping API on NpgsqlDbContextOptionsBuilder, and removed hacky reflection-based pulling of enum type mappings from the Npgsql ADO.NET layer. This is #3063.
- Thanks to the above, NpgsqlTypeMappingSource (a singleton service) no longer needs the NpgsqlDataSource (to pull enum mappings from). Changed DbDataSource to be scoped (when configured explicitly by the user via UseNpgsql()), allowing it to change across invocations. This fixes #2891.
- When the new EF MapEnum() API is used, we now create a data source internally, configuring it with the enum definition as well, so users no longer need to configure both EF and ADO.NET for the enum. This is #1026.
- The internally created data source is (obviously) a singleton, and if the user passes different connection strings to UseNpgsql(), we throw. This means it's no longer possible to do both enums and switch connection strings (breaking change).
- Similarly to enums, added infrastructure to allow EF plugins to participate in the NpgsqlDataSourceBuilder configuration. This is used by the NTS and NodaTime plugins to add the corresponding ADO.NET-level plugins.
- Removed all enum- and plugin-related global configuration in the tests, switching to the above new data source APIs.
- Now that the plugins just configure the internal data source and the obsolete global type mapper is no longer used, merged the NodaTime test project into the general test project (NodaTime previously had its own project to avoid interence via the global type mapper).
- Added a convention to add enums to the model based on the new, explicit user API above. This means that the single EF MapEnum() in UseNpgsql() is now sufficient to configure EF's type mapping, the ADO.NET type mapping, and cause the enum to be created in the database. This completes #1026.
Future task: add NpgsqlDataSourceBuilder to NpgsqlDbContextOptionsBuilder, to allow easy configuration of Npgsql via the EF API. Accessing the DataSourceBuilder would also count as "requires internal data source", just like enums/plugins.
Fixes #2891 Fixes #3063 Fixes #1026
See comments below for last remaining tasks.
/cc @NinoFloris @ajcvickers
@NinoFloris can I get another quick review from you on the added changes etc.? Especially on the new logic adding the ConcurrentDictionary for multiple data sources in NpgsqlDataSourceManager, and the concurrency handling around that?
Hi, I upgraded the Npgsql.EntityFrameworkCore.PostgreSQL package to v7.0.18 from v7.0.3 and I get the ManyServiceProvidersCreatedWarning during integration tests. This PR should fix the ServiceProviderCache issue, if I'm not wrong. Will there be a version with these changes soon?
Thank you for your work
This PR is for 9.0 only - these changes will not be merged back to patch releases for previous versions (too complex/risky). Note also that 7.0 is out of support.