在单例实例化后更改 ninject 依赖项的实现

Change implementation of ninject dependency after singleton instantiation

所以,我在 xamarin 项目中有一个视图模型 class,我在应用程序启动时通过 ninject 绑定将一些依赖项注入其中。其中之一是 IDialogService。

当我的应用程序中的 MainPage 发生变化时,它会引发一个 属性 changed 事件,并且我重新绑定对话框服务的实现,因为它与 MainPage 相关联。

如果我的视图模型已经使用 DialogServiceA 创建,然后当 MainPage 更改时我们重新绑定到 DialogServiceB,我的视图模型将使用服务 A 还是 B?我认为它使用的是 A,因此不会显示在 UI 中,因为它绑定到不再存在的 MainPage。

所以,如果是这种情况,我如何动态更改我的对话服务,然后更新已经实例化的 classes,而不更改所有内容,以便在每次使用时从容器中获取当前对话服务(因此根本不注入它,而是做更多的服务定位器)

此外,如果这种方法完全错误,请纠正我。

你是对的。 Re-configuration 容器不影响已经实例化的对象。

如果您想在没有 re-instanciating 依赖项(父 ViewModel)的情况下更改依赖项,您有几种可能性:

  • 每次都使用工厂实例化服务。实施 Abstract Factory (Site by Mark Seeman) or use Ninject.Extensions.Factory 来做到这一点
  • 不是直接注入服务,而是注入适配器。然后适配器将请求重定向到当前适当的服务。为此,可以将所有服务注入到适配器中,或者您可以像上述可能性一样使用工厂。
  • 不是直接注入服务,而是注入代理。代理与适配器非常相似,但不是专门为每个方法/属性 重定向编写代码,而是通过拦截器编写通用重定向。这是一个 tutorial on castle dynamic proxy

然而,在一天结束时,我相信您还需要一种方法来管理何时更改服务/它应该是什么。可能有一种设计替代方案不依赖于以这种方式交换对象。这将使它更容易(因此更好?)设计。

编辑:我刚刚看到您也将问题标记为 xamarin-forms。在那种情况下,很可能不会选择使用动态代理或 ninject.extensions.factory(它也依赖于动态代理)。为什么?并非所有平台都支持动态代理/IL 发射,AFAIR 特别是在 Apple 设备上无法完成。