[英]Start Long-Running Process With DBContext Access Before Returning
我正在嘗試找出使用dotnet核心和依賴項注入來處理特定情況的正確方法。 我有一台僅用作后端的Web API服務器,具有單獨的Vue前端。 API端點之一需要觸發一個長時間運行的下載過程,但隨后立即返回而無需等待該過程完成。 我遇到的困難是,長時間運行的進程在整個運行過程中都需要數據庫訪問權限。 我有一個DownloadHelper類,要像這樣單例添加:
services.AddSingleton<DownloadHelper>();
我想讓DownloadHelper的構造函數看起來像這樣,以便我可以通過依賴項注入傳遞數據庫上下文。 DownloadHelper類如下所示:
public class DownloadHelper
{
private CoreTestContext _context;
public DownloadHelper(CoreTestContext dbContext)
{
_context = dbContext;
}
public async Task DownloadFile(Test item, string url) {
// Download the file from url
// Add details of downloaded file to the test object
item.Files.Add(new TestFile {Name = "NewFile", Path = "FilePath"});
_context.SaveChanges();
}
}
像這樣從Web API控制器(稱為TestController,因為它是繼承自Controller的,所以僅是作用域控制器)進行調用。 請注意,_downloadHelper由API控制器的構造函數設置,並通過依賴項注入傳遞:
public class TestController : Controller
{
private DownloadHelper _downloadHelper;
public TestController(CoreTestContext context, DownloadHelper downloadHelper)
{
_downloadHelper = downloadHelper;
}
[Route("api/test/{id}/testfile"]
[HttpPost]
public async Task<IActionResult> DownloadTestFile(Guid id) {
var test = _context.Tests.FirstOrDefault(x => x.Id == id)
_downloadHelper.DownloadFile(test);
// return without waiting for download to complete
return Ok(book);
}
}
我遇到的問題是CoreTestContext是作用域的,因此單例無法接收它。 我應該如何正確設置呢? 我也嘗試過使DownloadHelper成為作用域,但是當我這樣做時,由於TestController返回並被處置,因此DownloadFile中的_context.SaveChanges()調用將無法工作,因此在實際下載完成之前處置DownloadHelper及其上下文。 我收到一個錯誤消息說_context已經被處理掉了。 設置仍可以返回API控制器的調用的正確方法是什么?
您可以創建一個工廠類來創建CoreTestContext
然后將其傳遞給DownloadHelper
類。
public class CoreTestContextFactory
{
private readonly IServiceProvider _sp;
public CoreTestContextFactory(IServiceProvider sp)
{
_sp = sp;
}
public CoreTestContext CreateDbContext()
{
return _sp.GetRequiredService<DataContext>();
}
}
將其注冊為單例:
services.AddSingleton<CoreTestContextFactory>();
現在將其注入您的單例課程:
public class DownloadHelper
{
private CoreTestContextFactory _factory;
public DownloadHelper(CoreTestContextFactory dbContextFactory)
{
_factory = dbContextFactory;
}
public async Task DownloadFile(Test item, string url) {
// Download the file from url
// Add details of downloaded file to the test object
using(var context = _factory.CreateContext())
{
item.Files.Add(new TestFile {Name = "NewFile", Path = "FilePath"});
_context.SaveChanges();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.