2017-09-26 14 views
0

在實體框架核心上使用帶有sqlserver的asp.net核心,我們有一個端點用於我們休息的api,我們希望能夠被激發並忘記。services.AddDbContext在使用異步方法之前使用對象

在啓動時,我們註冊的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(); 
     } 
    } 
} 

的問題是,調用開始事務時始終處置ctx.Database。我的直覺是,一旦控制器完成並且返回的結果超出範圍,框架就會調用dispose。

有人可以證實我的懷疑或告訴我發生了什麼,如果可能的話,一種方法來解決它,同時仍然保持火災,忘記架構?

+1

你需要等待*爲了*異步方法來等待他們完成,即'等待injectedLogic.doWorkAsync(參數);' – poke

+0

點是我不希望在發送ok響應之前等待它完成。 –

回答

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(); 
}