簡體   English   中英

返回之前,先使用DBContext Access啟動長時間運行的進程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM