- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们在 ASP.NET Web Api 应用程序中使用 Ninject,我们将 DbContext
与 InRequestScope
绑定(bind)>。这适用于我们的大多数请求,因为它们同步完成所有工作,因此可以在请求完成后安全地处理上下文。
但是,我们根据请求执行异步 Web 服务调用,该调用具有作为回调传递的延续方法,并且该回调方法需要使用数据库上下文。但是我们的请求不应该等待异步服务调用完成,而是立即返回(这是一个明确的要求)。
这是该情况的一个简化示例。
public class MyController : ApiController
{
private readonly MyDbContext dbContext;
private readonly SomeWebService service;
public MyController(MyDbContext dbContext, SomeWebService service)
{
this.dbContext = dbContext;
this.service = service;
}
public IHttpActionResult MyActionWithAsyncCall()
{
// Doing stuff.
// Calling webservice method, passing the Callback as the continuation.
service.MethodWithCallback(param1, param2, this.Callback);
// Returning without waiting for the service call to be completed.
return Ok();
}
private void Callback()
{
// Trying to use the DbContext:
var person = dbContext.People.First();
// The above line sometimes throws exception, because the context has been disposed.
}
}
Ninject 应该如何处理这种情况?有没有办法显式地“延长”绑定(bind) DbContext
实例的生命周期?还是 Callback 方法应该创建全新的 DbContext
?如果应该,它应该使用什么范围?
最佳答案
无法通过 .InRequestScope()
显式延长对象的生命周期。扩展到请求结束后。
如果没有业务要求请求和@回调期间的工作必须在单个事务中发生,我会使用两个 DbContext
实例。一个在请求期间,一个在回调期间。注意:据我所知,这也意味着您不能从第一个上下文中获取实体并在第二个上下文中更新/保存它。这意味着您只能将标识符(以及与操作相关的其他数据)从请求传递到回调。回调必须“创建”一个新的 DbContext 并从上下文中检索相应的实体。
作为替代方案,您可以为这种特殊情况声明一个特殊绑定(bind)。 Ninject 支持所谓的 contextual bindings .这意味着您将有两个绑定(bind),标准绑定(bind)和上下文、特殊情况绑定(bind):
Bind<DbContext>().ToSelf().InRequestScope();
Bind<DbContext>().ToSelf()
.WhenInjectedInto<SomeController>();
请注意,第二个绑定(bind)未指定范围 - 这意味着 SomeController
负责电话.Dispose()
.在您的情况下,这意味着回调必须处理上下文。您还需要在所有错误情况下处理上下文(回调代码中的错误,触发回调之前发生的错误,......)。
此外,实际上您的应用程序可能更复杂并且 .WhenInjectedInto<SomeController>
是不够的/不正确的,因为您可能想将相同的实例注入(inject) Controller 加上存储库和查询对象..什么不是。
这意味着您将需要范围界定,但范围不同于 .InRequestScope()
.您可以使用 .InCallScope()
或命名范围 - 两者都包含在 named scope extension 中.
此外,您需要调整 When
健康)状况。您可以调整它以遍历请求并查看是否有 FooController
请求链中的任何位置。但这不是很高效,相反我建议使用 ninject IParameter
指定您想要特殊情况处理。参数将是:
public class NonRequestScopedParameter : Ninject.Parameters.IParameter
{
public bool Equals(IParameter other)
{
if (other == null)
{
return false;
}
return other is NonRequestScopedParameter;
}
public object GetValue(IContext context, ITarget target)
{
throw new NotSupportedException("this parameter does not provide a value");
}
public string Name
{
get { return typeof(NonRequestScopedParameter).Name; }
}
// this is very important
public bool ShouldInherit
{
get { return true; }
}
}
这将应用于像这样的绑定(bind):
kernel.Bind<SomeController>().ToSelf()
.WithParameter(new NonRequestScopedParameter());
kernel.Bind<DbContext>().ToSelf()
.When(x => x.Parameters.OfType<NonRequestScopedParameter>().Any())
.InCallScope(); // or whatever scope you're using
关于c# - 如何使用 Ninject InRequestScope 处理异步调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26775080/
有人在 monodroid 项目中使用 ninject 吗? 如果是这样,将不胜感激有关实现这一目标的任何指示/细节。 最佳答案 我还没有尝试在 Mono For Android 中使用 Ninjec
我找到了this article关于 Ninject 早期版本中的上下文变量。我的问题有两个方面。首先,如何使用 Ninject 2 获得这种行为?其次,上下文变量是否沿着请求链传递?例如,假设我想替
我有一个场景,只要一个对象上的方法返回 true,多个并发 Web 请求就应该重用一个对象。有问题的对象是线程安全的。 所以我需要当前范围内的对象来确定它是否仍在范围内。使用 Ninject 完成此任
我刚刚使用 Ninject 3 更新了我的应用程序。将 App_Start 中的文件从 NinjectMVC3 更改为 NinijectWebCommon.cs。移动了我的文件,更新了 DLLs..
我在 MVC4 应用程序中使用 Ninject 进行 DI 和 Ninject.MVC3 扩展,特别是版本 3.0.0.6。 阅读documentation在 Ninject 的 wiki 上,使用
如何绑定(bind)InitializerForXXX (非通用实现)到 IInitializer (通用接口(interface))使用 Ninject Conventions以便请求 IIniti
我正在开发一个框架扩展,它使用 Ninject 作为 IoC 容器来处理动态注入(inject),但是我在尝试解决如何实现这一点时遇到了一些麻烦。 我的框架的期望是您将传递 IModule(s)所以它
我确信这是一个愚蠢的问题,因为我假设答案是“当对象被 Ninject 实例化时”......但我想仔细检查...... 为了提供更多关于我为什么问这个问题的背景信息,我有一个实现 NinjectHtt
与其手动绑定(bind)每个类,不如推荐哪些方法和模式(如果有)来自动设置绑定(bind)? 例如,绝大多数绑定(bind)看起来像这样: Bind.To(); 一旦模块变大,您最终可能会得到 100
我试图找到一种将构造函数参数传递给子类的构造函数的方法。 这些对象是不可变的,所以我更喜欢使用构造函数参数。 我遇到的问题是 ConstructorArgument 不继承到子实例化,并且以下语句不可
我正在尝试为事件代理/消息代理的开发找到最新的 Ninject 扩展。 我至少可以找到 3 个:messagebroker , weakeventmessagebroker和 bbveventbrok
我有一个 WebApi 服务,我正在尝试使用 Ninject BindHttpFilter 添加身份验证。 使用 BindHttpFilter 允许我将身份验证过滤器绑定(bind)到特定属性。 Au
Autofac 自动为 Func 生成工厂;我什至可以传递参数。 public class MyClass { public MyClass(Func a, Func b) {
我有一个类需要为其类中的一个方法使用 IRepository。 理想情况下,我希望避免将这种依赖关系解析到类的构造函数中,因此我在 Ninject 中发现了方法级注入(inject),并且想知道这是如
我看到了枚举给定服务(类型)的绑定(bind)列表的方法,但我找不到返回已加载模块中绑定(bind)的所有内容列表的方法。我正在寻找类似Kernel::IEnumerable GetAllRegist
对于初学者,我正在使用这个模块: public class AutoMapperModule : NinjectModule { public override void Load()
我想知道 ninject 是否有可能拦截我类的私有(private)方法。我正在尝试进行一些 aop 编程以动态注入(inject)日志记录机制。 最佳答案 不幸的是,所有要拦截的方法都必须是virt
我是 Ninject 的新手,正在努力让这个测试通过。 (此测试通过 Autofac,但行为在 Ninject 中似乎有所不同)。 [Test] public void RegisterInstanc
我在一个小项目中使用过 Ninject,但现在正在将一个较大的 Web 应用程序转换为 mvc,并且需要有关使用 Ninject 的帮助。在新的解决方案中,我拥有 mvc 站点并将一些功能拆分到单独的
目前,我正在使用 ninject 执行以下绑定(bind)的命令模式: kernel.Bind>().To(); kernel.Bind>().To(); kernel.Bind>().To(); 我
我是一名优秀的程序员,十分优秀!