Flutter依赖注入插件modular_di的使用
Flutter依赖注入插件modular_di的使用
简介
Modular DI 是一个用于Flutter应用程序的依赖注入库,它允许你通过模块化的方式来组织和管理依赖。Modular DI 提供了一个简单而灵活的方式来将你的应用拆分为多个模块,并在这些模块之间进行依赖注入。以下是关于如何使用 Modular DI 的详细说明和一个完整的示例项目。
功能特点
- Works with whatever router you love:支持与任何路由管理器(如 Go Router、Auto Route)集成。
- Keep your app tidy with a simple module system:通过模块系统保持应用结构清晰。
- Easy dependency injection:基于
auto_injector
实现简单的依赖注入。 - Modules can talk to each other through imports:模块之间可以通过导入相互通信。
- Modules load up and clean up smoothly:模块可以平滑地加载和清理。
- Drop in the ModuleWidget wherever you need it:可以在需要的地方使用
ModuleWidget
。 - Testing is a breeze with mock replacements:测试时可以轻松替换依赖。
- Lightning-fast dependency resolution using directed acyclic graphs:使用有向无环图实现快速的依赖解析。
快速开始
1. 添加依赖
在 pubspec.yaml
文件中添加 modular_di
依赖:
dependencies:
modular_di: ^latest_version # 请替换为最新版本
2. 创建模块
创建一个模块类,继承自 Module
,并在其中注册依赖项。例如,创建一个 UserModule
:
class UserModule extends Module {
[@override](/user/override)
List<Type> imports = []; // 如果需要导入其他模块,请在此处添加
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
// 注册依赖项
i.addSingleton<UserRepository>(() => UserRepositoryImpl());
i.addSingleton<UserService>(() => UserServiceImpl());
}
}
3. 初始化模块
在 main.dart
中初始化模块。你可以一次性注册所有模块,也可以分别注册模块,最后统一初始化。
一次性注册并初始化模块:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 注册并初始化模块
await ModulesManager.instance.initModules([
UserModule(),
AuthModule(),
]);
runApp(const MyApp());
}
分别注册模块,最后统一初始化:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 注册 CoreModule
ModulesManager.instance.registerModule(CoreModule());
// 注册 User 和 Auth 模块
ModulesManager.instance.registerModules([
UserModule(),
AuthModule(),
]);
// 初始化所有已注册的模块
await ModulesManager.instance.initRegisteredModules();
runApp(const MyApp());
}
4. 使用 ModuleWidget
访问依赖
在需要访问依赖的页面中使用 ModuleWidget
,并通过 Module.get<T>()
获取依赖项。例如:
class UserScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return ModuleWidget<UserModule>(
child: Builder(
builder: (context) {
// 获取依赖项,不监听变化
final userService = Module.get<UserService>(context);
return UserContent(service: userService);
},
),
);
}
}
5. 监听模块变化
如果你希望在模块发生变化时重新构建 widget,可以在获取依赖时设置 listen: true
。例如:
class UserProfileWidget extends StatefulWidget {
[@override](/user/override)
State<UserProfileWidget> createState() => _UserProfileWidgetState();
}
class _UserProfileWidgetState extends State<UserProfileWidget> {
late UserService _userService;
[@override](/user/override)
void didChangeDependencies() {
super.didChangeDependencies();
// 监听变化 - 当前模块或导入的模块被重置时,widget 会重新构建
_userService = Module.get<UserService>(context, listen: true);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Text(_userService.username);
}
}
6. 模块之间的依赖
模块可以依赖其他模块,通过 imports
属性来声明。例如,ProfileModule
依赖于 UserModule
:
class ProfileModule extends Module {
[@override](/user/override)
List<Type> imports = [UserModule]; // 导入 UserModule 的依赖
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
i.addSingleton<ProfileService>(ProfileServiceImpl.new);
}
}
7. 依赖注入类型
Modular DI 支持多种依赖注入方式:
- Singleton:
addSingleton<T>()
- 创建一个全局唯一的实例。 - Lazy Singleton:
addLazySingleton<T>()
- 第一次请求时才创建实例。 - Factory:
add<T>()
- 每次请求时都创建新的实例。 - Instance:
addInstance<T>()
- 注册一个已经存在的实例。 - Replace:
replace<T>()
- 替换现有的注册(适用于测试)。
8. 日志功能
Modular DI 内置了日志系统,默认是关闭的。你可以根据需要启用或禁用日志:
import 'package:modular_di/logger.dart';
// 启用日志
Logger.enable();
// 禁用日志
Logger.disable();
日志仅在调试模式下打印,因此可以安全地保留日志代码在生产环境中。
完整示例项目
以下是一个完整的示例项目,展示了如何使用 Modular DI 来管理多个模块及其依赖关系。
项目结构
lib/
├── features/
│ ├── core/
│ │ └── core_module.dart
│ ├── home/
│ │ └── home_module.dart
│ ├── message/
│ │ └── message_module.dart
│ └── profile/
│ └── profile_module.dart
└── main.dart
core_module.dart
import 'package:modular_di/modular_di.dart';
class CoreModule extends Module {
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
// 注册核心依赖
i.addSingleton<CoreService>(() => CoreServiceImpl());
}
}
home_module.dart
import 'package:modular_di/modular_di.dart';
class HomeModule extends Module {
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
// 注册首页依赖
i.addSingleton<HomeService>(() => HomeServiceImpl());
}
}
message_module.dart
import 'package:modular_di/modular_di.dart';
class MessageModule extends Module {
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
// 注册消息依赖
i.addSingleton<MessageService>(() => MessageServiceImpl());
}
}
profile_module.dart
import 'package:modular_di/modular_di.dart';
class ProfileModule extends Module {
[@override](/user/override)
List<Type> imports = [UserModule]; // 导入 UserModule 的依赖
[@override](/user/override)
FutureOr<void> registerBinds(InjectorRegister i) {
// 注册个人资料依赖
i.addSingleton<ProfileService>(ProfileServiceImpl.new);
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:modular_di/logger.dart';
import 'package:modular_di/modular_di.dart';
import 'features/core/core_module.dart';
import 'features/home/home_module.dart';
import 'features/message/message_module.dart';
import 'features/profile/profile_module.dart';
/// ### 应用程序的所有模块
/// 用于初始化依赖
final modules = <Module>[
CoreModule(),
MessageModule(),
HomeModule(),
ProfileModule(),
];
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Logger.enable(); // 启用日志
await ModulesManager.instance.initModules(modules); // 初始化模块
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
initialRoute: '/',
routes: {
'/': (context) => const ModuleWidget<HomeModule>(child: HomeScreen()),
'/message': (context) => const ModuleWidget<MessageModule>(child: MessageScreen()),
'/profile': (context) => const ModuleWidget<ProfileModule>(child: ProfileScreen()),
},
);
}
}
// 示例页面
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
final homeService = Module.get<HomeService>(context);
return Scaffold(
appBar: AppBar(title: Text('Home')),
body: Center(child: Text(homeService.getMessage())),
);
}
}
class MessageScreen extends StatelessWidget {
const MessageScreen({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
final messageService = Module.get<MessageService>(context);
return Scaffold(
appBar: AppBar(title: Text('Message')),
body: Center(child: Text(messageService.getMessage())),
);
}
}
class ProfileScreen extends StatelessWidget {
const ProfileScreen({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
final profileService = Module.get<ProfileService>(context);
return Scaffold(
appBar: AppBar(title: Text('Profile')),
body: Center(child: Text(profileService.getUsername())),
);
}
}
服务实现
为了使示例更完整,以下是各个服务的简单实现:
core_service.dart
class CoreService {
String getMessage() {
return "This is the core service.";
}
}
class CoreServiceImpl implements CoreService {
[@override](/user/override)
String getMessage() {
return "This is the core service implementation.";
}
}
home_service.dart
class HomeService {
String getMessage() {
return "Welcome to the home page!";
}
}
class HomeServiceImpl implements HomeService {
[@override](/user/override)
String getMessage() {
return "Welcome to the home page! This is the implementation.";
}
}
message_service.dart
class MessageService {
String getMessage() {
return "You have no new messages.";
}
}
class MessageServiceImpl implements MessageService {
[@override](/user/override)
String getMessage() {
return "You have 3 new messages!";
}
}
profile_service.dart
class ProfileService {
String getUsername() {
return "Unknown User";
}
}
class ProfileServiceImpl implements ProfileService {
[@override](/user/override)
String getUsername() {
return "John Doe";
}
}
更多关于Flutter依赖注入插件modular_di的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter依赖注入插件modular_di的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用modular_di
进行依赖注入的示例代码。modular_di
是一个强大的依赖注入库,与modular
路由库紧密集成,但也可以独立使用。
首先,确保你的pubspec.yaml
文件中添加了modular_di
依赖:
dependencies:
flutter:
sdk: flutter
modular_di: ^latest_version # 替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们来看一个具体的代码示例。
1. 创建一个服务类
首先,创建一个简单的服务类,比如一个用户服务:
// user_service.dart
import 'package:modular_di/modular_di.dart';
@Injectable()
class UserService {
String getUserName() {
return "John Doe";
}
}
2. 配置依赖注入
在应用的入口文件(通常是main.dart
)中配置依赖注入:
// main.dart
import 'package:flutter/material.dart';
import 'package:modular_di/modular_di.dart';
import 'user_service.dart';
void main() {
// 初始化依赖注入模块
ModularDi.init();
// 注册依赖
ModularDi.bind<UserService>((i) => UserService());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
3. 在组件中使用依赖注入
现在,我们可以在组件中使用ModularDi.get()
来获取依赖注入的服务:
// home_screen.dart
import 'package:flutter/material.dart';
import 'package:modular_di/modular_di.dart';
import 'user_service.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 获取UserService实例
final UserService userService = ModularDi.get<UserService>();
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Text('User Name: ${userService.getUserName()}'),
),
);
}
}
4. 使用模块(可选)
如果你使用的是modular
库,你可以将依赖注入配置放在模块中。这里是一个简单的示例:
// app_module.dart
import 'package:modular/modular.dart';
import 'user_service.dart';
@Module()
abstract class AppModule {
@Bind()
UserService get userService => UserService();
}
然后在main.dart
中使用这个模块:
// main.dart (使用模块版本)
import 'package:flutter/material.dart';
import 'package:modular/modular.dart';
import 'app_module.dart';
void main() {
// 初始化Modular
Modular.init(modules: [
AppModule(),
]);
runApp(ModularApp(module: AppModule(), child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
在模块版本的HomeScreen
中,你可以直接使用Modular.get<UserService>()
来获取服务:
// home_screen.dart (使用模块版本)
import 'package:flutter/material.dart';
import 'package:modular/modular.dart';
import 'user_service.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 获取UserService实例
final UserService userService = Modular.get<UserService>();
return Scaffold(
appBar: AppBar(
title: Text('Home Screen'),
),
body: Center(
child: Text('User Name: ${userService.getUserName()}'),
),
);
}
}
以上就是在Flutter中使用modular_di
进行依赖注入的示例代码。根据你的项目需求,你可以选择直接使用ModularDi
或者结合modular
库使用模块化的方式来管理依赖注入。