Fluttin
一个为 Flutter 开发者设计的实用轻量级依赖注入框架。
入门
这是 koin 的 Flutter 版本,在用法上与原始的 koin 基本相同。只是 Dart 的闭包不支持接收者类型,所以在该类中看起来有点复杂,但原理是相同的。关于 DI 的概念,请参考 koin 官方网站:https://insert-koin.io/
您需要在项目开始时执行 startFluttin。
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
initFluttin();
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
Future<void> initFluttin() async {
startFluttin((FluttinApplication application) {
application.modules(<Module>[
Modules.module,
Modules.screenModule,
Modules.serviceModule,
Modules.dbModule,
]);
});
}
}
然后在 libs/ 中创建 modules.dart
class Modules {
static Module module = module((Module module) {
module.factory((Scope scope, DefinitionParameters parameters) =>
MyGameRepository(
scope.get(), scope.get(), scope.get(), scope.get(), scope.get()));
});
static Module screenModule = module((Module module) {
module.scope<ScreenScope>((scopeSet) {});
});
static Module serviceModule = module((Module module) {
module.single((Scope scope, DefinitionParameters parameters) =>
ServiceManager.instance);
module.single((Scope scope, DefinitionParameters parameters) =>
scope.get<ServiceManager>().gatewayService);
});
static Module dbModule = module((Module module) {
module.single(
(Scope scope, DefinitionParameters parameters) => DBUtils.appDatabase);
module.single((Scope scope, DefinitionParameters parameters) =>
scope.get<AppDatabase>().screenDao);
});
}
您无需关注此类中其他类的生成方式
class MyGameRepository {
MyGameRepository(this._appInfoDao, this._downloadPackageDao,
this._taskInfoDao, this._userAppDao, this._appVirtualDao);
final AppInfoDao _appInfoDao;
final DownloadPackageDao _downloadPackageDao;
final DownloadTaskDao _taskInfoDao;
final UserAppDao _userAppDao;
final AppVirtualDao _appVirtualDao;
}
以下是一个简单的说明
- 如果您想使用它,您可以直接使用 inject() 来生成它
class _XXState extends State<XXWidget> {
MyGameRepository _myGameRepository = inject();
@override
Widget build(BuildContext context) {
return Scaffold();
}
}
-
如果您想编写一个模块,有几种提供它的方式
- factory: 每次 inject() 都会生成一个新实例。
- single: 只有第一次 inject() 会生成新实例,之后将使用首次生成的实例。这相当于单例的概念。
- scoped: 当满足作用域条件时,只有第一次 inject() 会生成新实例,之后会重复使用。例如:scope=UserScope,这意味着当用户登录时,从 inject() 输出的实例是相同的,当用户注销后再次登录时,会再次尝试生成新实例。可以理解为用户登录时的单例。
-
如果我想生成的类中会用到其他类
- scope.get()
module.factory((Scope scope, DefinitionParameters parameters) => MessageScreenCubit(scope.get(), scope.get());
- scope.get()
-
如果我想动态传入参数
- DefinitionParameters
messageScreenCubit = inject(parameters: () { return DefinitionParameters(values: [ widget.conversation, widget.conversationId, widget.targetUserId, ]); });
module.factory((Scope scope, DefinitionParameters parameters) { return MessageScreenCubit(conversation: parameters[0], conversationId: parameters[1], userId: parameters[2], ); });
- DefinitionParameters
-
如果我想在模块中为接口提供不同的实现
-
qualifier
class _XXState extends State<XXWidget> { Animal animal = inject(qualifier: StringQualifier('dog')); @override Widget build(BuildContext context) { return Scaffold(); } }
module.factory<Animal>( (Scope scope, DefinitionParameters parameters) => Dog(), qualifier: StringQualifier('dog') ); module.factory<Animal>( (Scope scope, DefinitionParameters parameters) => Cat(), qualifier: StringQualifier('cat') );
-