返回之前

时间:2019-07-14 02:20:34

标签: c# entity-framework dependency-injection .net-core

我正在尝试找出使用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控制器的调用的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以创建一个工厂类来创建db <- read.csv("sample.csv", header = FALSE) class(db) db并将其传递给您的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>();