我现在已经在 Google 上四处搜寻,以找到有关如何将 Ninject 一起使用的异步/等待操作的任何有用示例。我自己也尝试了一点,以找到任何可以使其实际工作的模式,而无需编写大量代码,但我还没有设法使其工作。
采取最简单的基本问题描述就是Entity Framework DbContext
是在每个请求范围的基础上创建的(它是一个 ASP.NET MVC 应用程序),但是如果您尝试调用任何 *Async
方法它将失败,并显示它已经在执行(这很明显)。
所以,我需要的是调用 Kernel.Get<MyContext>()
创造独特的 DbContext
使用 Ninject 的对象以及 Ninject 负责其生命周期的对象。使用 BeginBlock()
或将范围更改为 InTransientScope()
这不是一个真正的选择,因为第一个将使用单独的 block 和处理这些 block 而使代码变得相当繁重,而后者设置的调用者代码负责处理 DbContext
.
我想做的代码的 POC 示例:
var context1 = NinjectKernelReference.Get<MyContext>(); //I want this to be a unique reference
var context2 = NinjectKernelReference.Get<MyContext>(); //I want this to be a unique reference
var task1 = context1.Customers.Where(c => c.ZipCode == "4444")
.Select(c => new {
c.Name,
c.PhoneNumber
})
.Take(50)
.ToArrayAsync();
var task2 = context2.Customers.CountAsync(c => c.ZipCode == "4444");
Task.WaitAll(task1, task2);
return new Result { task1.Result, task2.Result };
那么,有没有办法以“简单”的方式解决这个问题?
最佳答案
这是您可以自己控制对象创建的方式:
public interface IContextFactory {
MyContext Create();
}
kernel.Bind<IContextFactory>().ToFactory // requires ninjext.extensions.factory
(Factory Extension Link)
用法:
using(var context1 = IContextFactory.Create())
using(var context2 = IContextFactory.Create())
{
var task1 = context1.Customers.Where(c => c.ZipCode == "4444")
.Select(c => new {
c.Name,
c.PhoneNumber
})
.Take(50)
.ToArrayAsync();
var task2 = context2.Customers.CountAsync(c => c.ZipCode == "4444");
Task.WaitAll(task1, task2);
return new Result { task1.Result, task2.Result };
} // context get's disposed here
注意:这需要上下文 不是 被束缚
.InRequestScope()
, 否则,.Create()
将返回相同的对象来电。如果您有时需要它们
.InRequestScope()
有时不是,您可以考虑使用 ninject contextual binding
关于c# - Ninject 和异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25835206/