9

我将 Ninject.MVC3 包从 2.2.1.0 更新到 2.2.2.0。在我通过 BootStrapper.Kernel 属性访问内核对象之前,但在新版本中,内核属性被标记为过时。我收到警告说

“Public ReadOnly Property Kernel As Ninject.IKernel”已过时:“请勿将 Ninject 用作​​服务定位器”。

在新版本中是否有不同的方式访问内核?

4

4 回答 4

6

如果您有一个类(出于某种原因)需要从 Ninject 内核中检索对象,则可以将内核作为注入的属性/构造函数参数之一包含在该类中。从某种意义上说,这种模式更好,因为您明确声明特定类正在使用内核,而不是像服务定位器模式那样总是让它可用。

这假设 Ninject 自动将内核的实例绑定添加到自身。我知道它曾经这样做过,但如果没有,您可以手动添加绑定。

于 2011-05-18T16:09:30.393 回答
5

之所以将其标记为已过时并将在未来更改为内部,是因为如果可能的话,人们倾向于使用 Ninject 作为服务定位器。但是服务定位器是一个不应该使用的反模式。而且由于我们不想提供有助于构建设计不佳的软件的功能,因此将来会被删除。

如果这需要在您的代码中进行大量更改,这表明您的代码正遭受这种不适的依赖注入,您确实应该将其更改为更好的设计。

  1. 将您对内核的访问限制在最低限度。在 MVC 中,除了普通的构造函数注入之外,几乎没有其他需要的情况。因此,我的第一个建议是尽可能重构构造函数注入。
  2. 对于这些非常罕见的情况,您需要访问内核以创建其他对象,您应该将工厂注入需要新实例的类并将内核注入该工厂(如果构造函数有Kernel参数,它将接收实例进行注射)。

如果你真的想继续使用服务定位器,即使几乎每个人都会告诉你不要这样做,你必须自己保留一个静态引用。

于 2011-05-18T21:09:56.747 回答
2

In ASP.NET MVC 3, I think DepedencyResolver is a clean way to get a service locator.

于 2011-07-06T23:34:41.827 回答
0

您可以将Common Service Locator用作 Ninject 的服务位置挂钩。Common Service Locator 只允许您检索对象,而不是注入您已经拥有的对象。当然你可以绕过这个限制,但是你可以很容易地创建一个静态类来公开 Ninject 内核并引用它而不是 BootStrapper。

于 2011-05-18T17:42:54.243 回答