-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Start steering users away from AddDbContext/OnConfiguring #35481
Comments
According to the documentation, AddDbContextFactory does register the context as a scoped service. I think it's just the pooling version that doesn't. The factory extension allows registering a scoped factory too, which I think would have the same problems, so this would be about guiding people towards singleton factories specifically. |
Thanks for that @stevendarby, sounds right. It also makes this more difficult. |
We already have |
Makes sense @AndriySvyryd. @stevendarby's re your comment above, looking at the source code, unless I'm missing something, AddDbContextFactory does register the factory with a Singleton lifetime by default - which documentation do you see which says it does Scoped? But regardless, you're right that if a user uses AddDbContextFactory but explicitly passes Scoped/Transient, they're effectively in the same situation as AddDbContext/OnConfiguring, since the options lambda will get reevaluated multiple times. We'd need to think about possibly discouraging that too... |
@roji the documentation (in the remarks) says the context is registered as scoped, counter to your point that it only registers a factory. |
Ah you're right - I see now (docs):
I've also confirmed that this is actually the case in the code. Unless I'm mistaken, that means that #26528 is effectively already implemented - users can simply use AddDbContextFactory and get both factory and context from DI (singleton factory + options, scoped context). |
|
@stevendarby yep! That's being done in #35484 (PR out). |
tl;dr start moving users towards factory-based patterns for configuring DbContext, to stop relying on EF's internal service provider cache to resolve the right service provider & singleton resources. This is important for supporting Cosmos, PostgreSQL, and possibly other providers.
When users specify options via AddDbContext/OnConfiguring, the lambda they provide for setting up the options gets executed repeatedly, possibly yielding different options for different contexts. While this can be useful in some scenarios (e.g. specifying different connection strings for different tenants), it also creates significant issues. To properly support this, EF manages an internal cache keyed on the options, so that the same service provider can be used if (and only if) singleton options do not have different values. This in turn requires EF to always be able to compare the options when doing cache lookups; but providers have arbitrary option configuration which may not be comparable at all: Cosmos has CosmosClientOptions, EFCore.PG has ConfigureDataSource() (accepting a lambda to configure the data source), etc.
We've discussed this, an there seems to be general agreement that it would be best to start moving away from these problematic configuration mechanisms, and towards factory-based DbContext instantiation, where the options are calculated only once, and then used for all contexts.
Note: some of the above was already previously discussed in #29597.
/cc @NinoFloris with whom I've discussed this in past.
The text was updated successfully, but these errors were encountered: