TL;博士
换成. provider
_ get_it
后者在全局范围内执行 DI,而不将其范围限定为 BuildContext。(它实际上有自己的使用字符串的可选范围机制namedInstance
。)
其余的部分...
我遇到了一个类似的问题,我相信这归结为 Provider 强制执行某种类型的(元?)架构,即小部件位于您可能称之为“代理金字塔”的顶部的一个事实。
换句话说,在这种风格中,小部件了解业务逻辑(因此称为 BLoC 架构),它们运行显示,与ViewController
iOS 普及的范式不同,也可能是 MVVM 设置。
在这种架构风格中,当一个小部件创建一个子小部件时,它也会为该小部件创建模型。这里的上下文可能很重要,例如,如果您同时显示同一个子小部件的多个实例,则每个实例都需要其自己的底层模型实例。在小部件或其后代中,您的 DI 系统将需要 Context 来选择正确的。请参阅BuildContext::findAncestorWidgetOfExactType
以了解原因/方式。
这种架构风格似乎受到普通 Flutter 的鼓励,它的范例包括 app-as-a-widget(“乌龟一路向下”)、非可视化小部件、布局小部件和用于 DI 的 InheritedWidget(供应商使用我相信)
但
现代应用程序框架库(例如 redux、mobx)鼓励相反类型的元架构:金字塔底部的小部件。
这里的小部件是“愚蠢的”,只是 UI 信号发生器和接收器。业务逻辑封装在“Store”中或通过与商店交互的“Actions”封装。小部件仅对正在更新的商店中的相关字段做出反应,并在用户与它们交互时发送动作信号。
你应该使用哪个?
根据我的经验,至少在屏幕空间较小的移动设备上,很少需要将模型范围限定到渲染树中的分支。如果它突然变得重要,那么还有很多其他方法可以处理它(索引数组、id 查找映射、namedInstances in get_it
),而不是将其链接到 UI 渲染的语义。
目前,在 iOS ViewControllers 上花费了太多时间,我是执行更好SoC的新系统的粉丝。并且个人发现 Flutter 的一切都是小部件的范式如果不加以照顾有时会显得有点混乱。但最终这是个人喜好。