Ninject中"范围","上下文"等有什么区别?

kal*_*ech 6 .net ninject ninject-extensions

范围,上下文,命名绑定(和激活块?)的Ninject概念能够在概念层面上分离和解释清楚吗?

例如,我有一个服务从数据库加载数据记录,对于每个记录,它通过Ninject工厂扩展构建一个"worker".服务和个体工作者都使用Entity Framework的对象上下文与数据库进行交互.ObjectContext通过构造函数注入到两者(以及其他共享依赖项).目前,它是单线程的,但最终的工人需要在并行自己的线程中运行,因此他们将需要自己的ObjectContext实例和明确的开始/配置的生命周期.ObjectContext实例需要在worker的"工作单元"的持续时间内共享(因此它不是瞬态的,因为它被注入到工作者使用的多个存储库中).我很难尝试获得此功能.

我天真地想要这样的东西(使用命名范围上下文保留扩展):

Bind<MyDbContext>().ToSelf();
Bind<MyService>().ToSelf();

Bind<IWorkerFactory>().ToFactory().InThreadScope();  // scope prob not necessary

Bind<MyWorker().ToSelf().DefinesNamedScope("workerScopeName");
Bind<MyDbContext>().ToSelf().InNamedScope("workerScopeName");
Run Code Online (Sandbox Code Playgroud)

显然(至少对Ninject用户来说很明显)会因MyDbContext导致"多个匹配绑定..."错误.在阅读了更多内容之后,我现在认为我应该为worker 使用命名绑定,它是ObjectContext.我我仍然还需要范围的,这样我可以明确地处理当工作完成(并有它从ninject范围处理Dispose方法)的ObjectContext的.

在任何情况下,我仍然主要猜测,我发布这个问题,希望有人可以在Ninject中澄清这些概念.

Rem*_*oor 9

上下文:当前解析的元信息.它指定对象树中将注入当前已解析对象的位置.(例如,当前解析的对象将被注入到类A的构造函数中,它被注入到类B中,....)例如,它可以用于确定绑定是否适用于当前上下文中的一个When重载.它也被传递给流利语法的许多其他回调(例如InScope,OnActivation,....)

范围:定义对象的生命周期以及何时重用现有实例,有许多预定义范围以及可以从当前上下文指定范围的通用范围(InScope(ctx => ...)

命名绑定:绑定的元信息.可以与上下文结合使用.例如,绑定仅适用于当前上下文中任何父绑定具有某个名称的情况.

激活块:( 截至Ninject 2.x - 3.x,未来版本可能会有所改变).在激活块内,每个绑定都会更改为将激活块作为范围.这意味着将忽略绑定上指定的作用域.将为一个激活块上的解析创建一个实例.

我个人不会使用该功能,因为它忽略了所有其他范围,例如InSingletonScope.更好地使用Ninject.Extensions.NamedScope提供的范围.

关于你的例子:由于你有两个MyDbContext绑定,你需要为它们添加条件.例如WhenAnyAncestorNamed.或者你可以使用另一个Scope,就像InCallScope()只有一个绑定一样.