WidjectContainer
Flutter 的依赖注入包
一个简单的 DI 包,用于帮助您的 Flutter 应用程序构建松散耦合的组件。
特点
- 作用域内的显式构造函数注入。
- 不使用反射/镜像。
- 嵌套作用域支持,按 widget 类型隔离依赖项。
- 作用域依赖项的异步初始化。
安装
-
打开您项目的 pubspec.yaml 文件。
-
添加一个 git 包依赖项
dependencies: # -------------------------- # # Your existing dependencies # # -------------------------- # widject_container: git: url: https://github.com/zlatancld/WidjectContainer -
执行
flutter pub get。
基本用法
创建一个连接到 widget 的作用域并注册所需的类型。类型引用在作用域内请求时自动解析。
class AppScope extends Scope<AppWidget> {
AppScope(): super(null);
@override
void configure(ContainerRegister register) {
register.add((r) => HelloWorldProvider(), Lifetime.transient).as<MessageProvider>();
register.addWidget((r, key, _) => AppWidget(r.get(), key: key));
}
}
类的位置
abstract class MessageProvider {
String getMessage();
}
class HelloWorldProvider implements MessageProvider {
@override
String getMessage()
=> "Hello world!";
}
class AppWidget extends StatelessWidget {
final MessageProvider _messageProvider;
const AppWidget(this._messageProvider, {super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WidjectContainer Demo',
home: Scaffold(
body: Text(_messageProvider.getMessage())
)
);
}
}
main 函数中使用作用域的示例是
void main() {
var app = AppScope().getWidget();
runApp(app);
}
Widget Provider
使用 WidgetProvider 来实例化已在作用域中注册的 widget 类型。依赖项会按照作用域注册中定义的进行解析和显式注入。
注册示例
class AppScope extends Scope<AppWidget> {
...
@override
void configure(ContainerRegister register) {
...
register.addWidget((r, key, _) => NewWidget(r.get(), args, key: key));
}
}
通过 WidgetProvider 使用示例
class AppWidget extends StatelessWidget {
final MessageProvider _messageProvider;
final WidgetProvider _widgetProvider;
const AppWidget(this._messageProvider, this._widgetProvider, {super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WidjectContainer Demo',
home: Scaffold(
body: _widgetProvider.getWidget<NewWidget>())
)
);
}
}
嵌套作用域
将 widget 的实例化连接到新的作用域,注册类型并继承来自祖先作用域的引用。当创建需要全新依赖项的新屏幕时,这会很有用。
class ScreenScope extends Scope<ScreenWidget>{
ScreenScope(super.parentContainer);
@override
void configure(ContainerRegister register) {
register.addWidget((r, key, args) => ScreenWidget(...));
}
}
父作用域中作用域 widget 绑定的位置是
class AppScope extends Scope<AppWidget> {
...
@override
void configure(ContainerRegister register) {
...
register.addScopedWidget((r, key, _) => ScreenScope(r));
}
}
通过 WidgetProvider 使用示例
class AppWidget extends StatelessWidget {
final MessageProvider _messageProvider;
final WidgetProvider _widgetProvider;
const AppWidget(this._messageProvider, this._widgetProvider, {super.key});
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => _openChildWidget(context),
child: Text(_messageProvider.getMessage())
);
}
_openChildWidget(BuildContext context){
Navigator.push(context, MaterialPageRoute(
builder: (context) => _widgetProvider.getWidget<ScreenWidget>()));
}
}
鸣谢
WidjectContainer 的灵感来自
作者
许可证
MIT