services.AddDbContext在使用之前处理在异步方法中使用的对象

时间:2017-09-26 21:27:42

标签: c# asp.net-core entity-framework-core

在实体框架核心上使用带有sqlserver的asp.net核心,我们有一个我们想要解决的休息api的端点。

在启动时,我们使用框架

注册DBContext
services.AddDbContext<DBContext>(options=>options.UseSqlServer(/*connection string*/));

我们的控制器方法就像

[HttpPost(/*route*/)]
public ObjectResult doWork([FromBody] string[] args)
{
    IInjectedLogic.doWorkAsync(args);
    return new OkObjectResult("");
}

我们的逻辑类就像

public interface IInjectedLogic
{
    Task doWorkAsync(string[] args);
}

public class InjectedLogic:IInjectedLogic
{
    private DBContext ctx;
    private ILegacyWCFService wcfClient;
    private ILogger logger;

    public InjectedLogic(DBContext ctx,ILegacyWCFService wcfClient,ILogger logger)
    {
        this.ctx=ctx;
        this.wcfClient=wcfClient;
        this.logger=logger;
    }

    public async Task doWorkAsync(string[] args)
    {
        using(var transaction=ctx.Database.BeginTransaction())
        {
            try
            {
                string[] processed=await wcfClient.doOtherWorkAsync(args);
            }
            catch(Exception ex)
            {
                transaction.RollBack();
                logger.logError(ex);
            }
            transaction.Commit(); 
        }
    }
}

问题是在调用begin transaction时始终处理ctx.Database。我的预感是,一旦控制器完成并且返回的内容超出了范围,框架就会调用dispose。

有人可以证实我的怀疑或告诉我真正发生了什么,并且如果可能的话,还有一种方法可以解决这个问题,同时仍然保持着火灾并忘记建筑?

1 个答案:

答案 0 :(得分:0)

您可以从DI容器创建新范围。您的依赖项的新实例将得到解决,并在完成时处理。

示例:

...
using Microsoft.Extensions.DependencyInjection;
...

[HttpPost(/*route*/)]
public IActionResult DoWork([FromBody] string[] args)
{
    using (var scope = Request.HttpContext.RequestServices.CreateScope())
    {
        var worker = scope.ServiceProvider.GetService<IInjectedLogic>();
        worker.doWorkAsync(args);
    }

    return NoContent();
}