可以将范围,上下文,命名绑定,(和activation block?)的Ninject概念分开并清楚地解释在概念层面?
作为一个例子,我有一个从数据库加载数据记录的服务,并且对于每个记录,它通过Ninject工厂扩展构造一个“worker”。服务和个体工作者都使用Entity Framework的对象上下文与数据库进行交互。 ObjectContext通过构造函数注入到两者(以及其他共享依赖项)。目前它是单线程的,但最终工作者需要并行运行自己的线程,因此他们需要自己的ObjectContext实例和显式的start / dispose生命周期。 ObjectContext实例需要在worker的“工作单元”的持续时间内共享(因此它不是瞬态的,因为它被注入到工作者使用的多个存储库中)。我很难尝试获得此功能。
我天真地想要这样的东西(使用named scope和context 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中澄清这些概念。
答案 0 :(得分:9)
上下文:当前解析的元信息。它指定对象树中将注入当前已解析对象的位置。 (例如,当前解析的对象将被注入到类A的构造函数中,该构造函数被注入到类B中,....)例如,可以使用它来确定绑定是否适用于当前上下文中的一个{{ 1}}重载。它也被传递给流利语法的许多其他回调(例如InScope,OnActivation,....)
范围:定义对象的生命周期以及何时重用现有实例,有许多预定义的范围以及可以从当前上下文指定范围的通用范围({{1 }})
命名绑定:绑定的元信息。可以与上下文结合使用。例如。绑定仅在当前上下文中适用时,任何父绑定都具有某个名称。
激活阻止:(截至Ninject 2.x - 3.x,未来版本可能会发生变化)。在激活块内,每个绑定都会更改为将激活块作为范围。这意味着将忽略绑定上指定的作用域。将为一个激活块上的解析创建一个实例。
我个人不会使用该功能,因为它忽略了When
之类的所有其他范围而存在缺陷。更好地使用Ninject.Extensions.NamedScope给出的范围。
关于您的示例:由于您有两个InScope(ctx => ...
绑定,因此需要为它们添加条件。例如InSingletonScope
。或者您可以使用另一个范围,例如MyDbContext
只有一个绑定。