Closed higginsddh closed 2 days ago
I might get round to supporting this on registration, there is a open PR but it needs changing to support passing the IServiceProvider in the invoking delegate as well as on exceptions. This hasn't been a priority for me though because I think MS will include the functionality in this package in Core 3.0.
However because it is just a delegate you can pass IServiceProvider into the delegate, just remember to create a new scope rather than just get the service.
public EmailController(BackgroundQueue backgroundQueue, IServiceProvider serviceProvider)
{
_backgroundQueue = backgroundQueue;
_serviceProvider = serviceProvider;
}
[HttpPost, Route("/")]
public IActionResult SendEmail([FromBody]emailRequest)
{
_backgroundQueue.Enqueue(async cancellationToken =>
{
using (var scope = _serviceProvider.CreateScope())
{
var scopedProcessingService = scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
scopedProcessingService.DoWork();
}
});
return Ok();
}
Caveat I haven't tested this, but see no reason why this shouldn't work because IServiceProvider is a singleton.
Hi. I tried to get this going. I have an app that downloads big files in the background but needs to write to the database during this process for progress etc.
Here is Startup.cs
`public void ConfigureServices(IServiceCollection services)
{
services.Configure
services.AddBackgroundQueue(onException: exception =>
{
Console.WriteLine(exception.Message);
throw exception;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<Models.db_productpriceContext>();
services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI(UIFramework.Bootstrap4)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddScoped<IDownloadRepository, DownloadRepository>();
services.AddScoped<IDownloadHandler, DownloadHandler>();
}`
Here is DownloadsController.cs ` using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using DalSoft.Hosting.BackgroundQueue; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Updater1.BackgroundTasks; using Updater1.DAL; using Updater1.Models;
namespace Updater1.Controllers { public class DownloadsController : Controller { private readonly db_productpriceContext _context; private readonly BackgroundQueue _backgroundQueue; private readonly IDownloadRepository _downloadRepository; private IServiceProvider _serviceProvider;
public DownloadsController(db_productpriceContext context, BackgroundQueue backgroundQueue, IDownloadRepository downloadRepository, IServiceProvider serviceProvider)
{
_context = context;
_downloadRepository = downloadRepository;
_backgroundQueue = backgroundQueue;
_serviceProvider = serviceProvider;
}
....
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,FeedId,DateValidUntil")] Download download)
{
if (ModelState.IsValid)
{
_downloadRepository.InsertDownload(download);
download.DatedownloadStarted = DateTime.Now;
_downloadRepository.Save();
IServiceScopeFactory scopeFactory = _serviceProvider.GetRequiredService<IServiceScopeFactory>();
using (var scope = scopeFactory.CreateScope())
{
_backgroundQueue.Enqueue(async cancellationToken =>
{
using (var scopedDownloadHandler = scope.ServiceProvider.GetRequiredService<IDownloadHandler>())
{
await scopedDownloadHandler.DownloadAsync(download);
}
});
}
return RedirectToAction(nameof(Index));
}
ViewData["FeedId"] = new SelectList(_context.Feed, "Id", "Name", download.FeedId);
return View(download);
}
`
I tried your code too but I keep getting Object already disposed on DeQueue method - is this significant.
I was trying to use something like this post:
Is this still going? Awesome Nuget, but I face same DI problem when trying to insert into db. It always states that any custom service I use in same controller is disposed.
Fully supported in v2.0.0
Updated in README.md has an example showing how to do this in v.2.0.0
v2.0 has a fully working EF example in the repo
Thanks for providing this library, looks really helpful!
Was wondering, how have you handled injecting dependencies into the queued task?
At https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2#consuming-a-scoped-service-in-a-background-task, they show injecting IServiceProvider into the hosted service to create a scope and pull services from that but don't see a way to do it with this library.