-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Hacky games around DI and context factories #24797
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
Conversation
|
We should also find out that highly-voted issue where people requested the solution to their problem and post it there to gather feedback. This PR is very likely to be ignored by actual customers. |
|
@smitpatel for sure, this is just an alternative design proposal. @ajcvickers do you know which issue it was? |
|
Am guessing maybe this is the issue: #626 |
|
@roji I don't fully understand what this change is trying to accomplish.
If you want both to use the same |
|
The point here is for the user to register their own factory implementation, but to have contexts from that implementation get injected directly via DI - and not the factory itself. Right now, if you register a factory, your controllers only get injected with that factory. This would allow people to use their own factories - include lifecycle stuff (like tenant ID) - but still get injected with a context (and not with a factory). Does that make sense? (this isn't an actual API proposal - it may be better to allow the user to specify their factory in AddDbContext instead).
This is already how the existing AddDbContextPool is implemented. This is indeed not optimal; for the ultra-high-perf mode, we'd probably recommend getting injected with the factory directly (not with the context) to avoid this lookup (am doing something like this for the TE Fortunes platform benchmark). (another option is to have a static factory, and reference that directly from the scoped lambda, but that's going outside of DI...). |
|
Closing this for now, we'll revisit DI, factories and pooling in 7.0. |
|
@roji - Can you save the commit if you want to in your fork so we can delete branch from here? |
|
All good, deleted. |
Alternative approach to #24768.
This hacky thing modifies AddDbContextFactory to also arrange for direct DbContext injection, via a lease mechanism that's very similar to what we already do for pooling. The user simply specifies the factory they want to use when setting up EF in DI, and do any customizations there.
For multi-tenancy, users would have to implement a factory like the following:
... and register it in DI as usual with AddDbContextFactory.
The big limitation at the moment is that IDbContextFactory manages creation, but not disposal. A bigger refactor could add Dispose or Return methods there, at which point it seems like DbContextPool could also be merged into PooledDbContextFactory (calling DbContext.Dispose would call into its factory's Return).
If we go down this route, users could also extend PooledDbContextFactory, and override the factory's methods to do nothing, as a way of getting rid of config snapshotting/resetting for ultra-high-perf (#24769), without needing a new flag and code path.
(The only thing I personally dislike is the additional ScopedDbContextLease which we need to disposal... if only the DI scope provider allowed us to register the DbContext for disposal instead...)
Complete sample user code
/cc @ajcvickers