Add failing test that exposes DbDataSource related bug. #3003
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
@roji I took your
DbDataSource
support implementation as a base for our Pomelo implementation and came across a subtle bug.This PR adds a test that fails.
The issue is that an old
DbDataSource
instance might be used by a laterDbContext
instance, if both contexts (the previous and the later one) are supposed to use aDbDataSource
instance that was added as a service to the application service provider.The reason seems to be that
NpgsqlOptionsExtension
is cached by the service provider cache and later reused, because none of its properties have changed (DataSource
isnull
in both cases (the previous and the later context), since theDbDataSource
instances are added via DI).Because
NpgsqlOptionsExtension
is cached, no newNpgsqlSingletonOptions
instance is created. But because it isNpgsqlSingletonOptions.Initialize()
where the application service provider is checked for a DI suppliedDbDataSource
instance, later calls then reuse the obsolete one from the time thatNpgsqlOptionsExtension
was cached.We workaround this issue by checking for
DbDataSource
services at the time we would actually need to, which is in ourIRelationalConnection
implementation. This might not be a good enough workaround for you, because you are accessing yourINpgsqlSingletonOptions.DataSource
property also fromNpgsqlTypeMappingSource
.(Using
INpgsqlSingletonOptions.ApplicationServiceProvider
would suffer from the same issue.)(It might be possible to pass the
CoreOptionsExtension
instance or theDbContextOptions
instance as an option (With...
) toNpgsqlOptionsExtension
and then check the service provider(s) it contains in theGetServiceProviderHashCode()
/ShouldUseSameServiceProvider()
methods so that theNpgsqlOptionsExtension
instance doesn't get cached if theNpgsqlDataSource
service (and/or the service provider?) changed. I did not analyze or test this in any way, however, since it seems that Pomelo works fine with our current implementation. So this might not work or might turn out to be unreliable (e.g. somebody might alter the immutableCoreOptionsExtension
instance after it has been passed, resulting in a new/cloned final instance). Anyway, just throwing it out there.).