Reputation: 21
I built a small web-app for college last semester and ran into an issue that I wasn't able to properly solve. The app is a price tracker that's using Selenium or curl to scrape products from webpages and track their price over time.
My issue is, how do I properly access the database context outside of the .cshtml.cs files? My current solution to this was to have a global variable that is assigned to the database context from the Main()
class as such:
public static ProductContext globalContext;
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
globalContext = services.GetRequiredService<ProductContext>();
Then off in the scraping class I could save the found information as such:
Program.globalContext.SaveChanges();
My global variable solution works for this, but it feels like a hacky solution at best. I had searched the internet as best I could, my professor wasn't able to offer a better solution either, but there has to be a way to do this right?
The full repository is here
Upvotes: 1
Views: 499
Reputation: 21
I finally figured this out for myself, after doing research for another school project involving asp.net.
While reading the asp.net documentation I noticed the Background task with hosted services feature. From there I was able to piece together a plan using dependency injection to pass IServiceProvider into the IJob whenever Quartz is set to run the job. I think part of my original problem was the fact that I was trying to pass the database context to the IJob Execute method, which Quartz complained about. I also found this article about background tasks with Quartz to be quite helpful in developing my solution.
My IJob now looks like:
public class scrapeJob : IJob
{
private IServiceProvider services {get; }
public scrapeJob(IServiceProvider service)
{
services = service;
}
async Task IJob.Execute(IJobExecutionContext context)
{
Console.Out.WriteLine("Begin Scheduled Job...");
using(var scope = services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ProductContext>();
var scraper = new scrape(dbContext);
await Task.Run(scraper.Scrape());
}
}
}
Link to Quartz.net
Upvotes: 1