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

时间:2013-01-29 23:06:53

标签: .net ninject ninject-extensions

可以将范围上下文命名绑定,(和activation block?)的Ninject概念分开并清楚地解释在概念层面?

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

我天真地想要这样的东西(使用named scopecontext preservation扩展名):

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

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

Bind<MyWorker().ToSelf().DefinesNamedScope("workerScopeName");
Bind<MyDbContext>().ToSelf().InNamedScope("workerScopeName");

显然(至少对Ninject用户来说很明显)由于MyDbContext导致“多个匹配绑定...”错误。在阅读了更多内容之后,我现在认为我应该使用named bindings作为worker,它是ObjectContext。我想想我还需要范围,这样我就可以在工作完成时显式处理ObjectContext(并且它具有来自ninject范围处理的dispose方法)。

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

1 个答案:

答案 0 :(得分:9)

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

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

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

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

我个人不会使用该功能,因为它忽略了When之类的所有其他范围而存在缺陷。更好地使用Ninject.Extensions.NamedScope给出的范围。

关于您的示例:由于您有两个InScope(ctx => ...绑定,因此需要为它们添加条件。例如InSingletonScope。或者您可以使用另一个范围,例如MyDbContext只有一个绑定。