我现在在 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
用法:
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
注意:这需要上下文不绑定(bind).InRequestScope()
,否则,将为 .Create()
返回相同的对象来电。
如果您有时需要它们.InRequestScope()
有时不是,您可能会考虑使用 ninject contextual binding
关于c# - Ninject 和异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25835206/