Skip to content
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

New topic: Getting the DbContext outside of a Controller #4782

Open
2 tasks
Rick-Anderson opened this issue Nov 13, 2017 · 5 comments
Open
2 tasks

New topic: Getting the DbContext outside of a Controller #4782

Rick-Anderson opened this issue Nov 13, 2017 · 5 comments
Labels
doc-enhancement re-Aditya @adityamandaleeka must review
Milestone

Comments

@Rick-Anderson
Copy link
Contributor

  • Getting the DbContext outside of a Controller
  • Accessing scoped services outside of an HTTP request.

per @davidfowl
There's enough confusion here that I think we should have a first class topic for it on the EF docs:

https://www.reddit.com/r/dotnet/comments/7cednh/how_to_grab_a_dbcontext_from_outside_a_controller/
We should probably also have something on accessing scoped services outside of an http request.

Can one of @ajcvickers or @divega provide the sample for Getting the DbContext outside of a Controller?

@rynowak @danroth27 who's the contact for Accessing scoped services outside of an HTTP request?

@Rick-Anderson Rick-Anderson added the Pri0 Urgent priority label Nov 13, 2017
@divega
Copy link
Contributor

divega commented Nov 13, 2017

Can one of @ajcvickers or @divega provide the sample for Getting the DbContext outside of a Controller?

@Rick-Anderson that really is a DI question, not an EF question 😸

By default AddDbContext<TContext>() registers TContext as scoped, so you want to create a DI scope first. There is already some guidance in the context of migrating from 1.x to 2.0:

https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#move-database-initialization-code

But not sure where else this could be useful besides initialization. E.g. the thread in reddit talks about a service that scheddules recurrent tasks rather tha servicing external requests. I imagine we would need general guidance on how to do that correctly.

BTW, @davidfowl pushed a change late in 2.0 which removed the need to create the DI scope if you needed to use a scoped service (e.g. a DbContext) inside Startup.Configure(), but it turns out that in 2.0 that is the last place where you want to do that anyway.

@Rick-Anderson Rick-Anderson added the Pri1 High priority, do before Pri2 and Pri3 label Nov 21, 2017
@Rick-Anderson
Copy link
Contributor Author

@scottaddie can you review this?

@scottaddie scottaddie self-assigned this Nov 21, 2017
@Rick-Anderson Rick-Anderson removed the Pri0 Urgent priority label Dec 13, 2017
@scottaddie scottaddie added the Help wanted Up for grabs. We would accept a PR to help resolve this issue label Mar 2, 2018
@scottaddie scottaddie removed their assignment Mar 14, 2018
@tnsturm
Copy link

tnsturm commented Jun 4, 2018

We have a real use case:

We're using

<PackageReference Include="Microsoft.Azure.EventHubs" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.EventHubs.Processor" Version="2.0.1" />

in our Asp.NET Core Application.

None of the 4 entry points (public EventHubProcessor(), OpenAsync(), CloseAsync(), ProcessEventsAsync()) are integrated in the DI system, so we have to be "creative" even when only using an ILogger.

Up to Asp.NET Core 2.0, we injected an IServiceProvider into Configure() of Startup, saved that into a static property of Startup and used that in the Eventprocessor Contructor with
_logger = Startup.Current.GlobalStaticServiceProvider.GetRequiredService<ILogger<EventHubProcessor>>();

This broke with asp.NET Core 2.1 because of aspnet/Hosting#1106, now the IServiceProvider injected into Configure() is scoped and most of the time disposed at the time the EventprocessorHost is created.

Now we have to be even more creative and safe this IServiceProvider in program.cs:

IWebHost host = webhostbuilder.Build();
Startup.Current.GlobalStaticServiceProvider = host.Services;
host.Run();

and fetch the ILogger in Eventprocessor Constructor with:

_logger = Startup.Current.GlobalStaticServiceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope().ServiceProvider.GetRequiredService<ILogger<EventHubProcessor>>();

None of these options are a clean solution and prone to fail in future asp.net core Versions. It would be very helpful if there would be easier ways to use the DI system in code paths which are not derived from IController or which are integrated with the DI system like Hangfire

@danroth27
Copy link
Member

@davidfowl

@davidfowl
Copy link
Member

None of these options are a clean solution and prone to fail in future asp.net core Versions. It would be very helpful if there would be easier ways to use the DI system in code paths which are not derived from IController or which are integrated with the DI system like Hangfire

Yes this is tricky as it hard to integrate when multiple systems want to be the owner of the container, and that's what going on here. Ideally you would register something in the DI container that activated the EventHubProcessor from the DI container. It looks like there's a factory though but I'm not 100% sure if it'll work well here.

@Rick-Anderson Rick-Anderson removed Help wanted Up for grabs. We would accept a PR to help resolve this issue Pri1 High priority, do before Pri2 and Pri3 labels Dec 11, 2019
@Rick-Anderson Rick-Anderson added re-Aditya @adityamandaleeka must review and removed PU labels Sep 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-enhancement re-Aditya @adityamandaleeka must review
Projects
None yet
Development

No branches or pull requests

7 participants