2.5 KiB
2.5 KiB
main.dart 与认证模块耦合
问题描述
当前 main.dart 直接依赖了 AuthBloc 和 AuthStarted,违反了依赖反转原则。
当前代码
// main.dart
import 'features/auth/presentation/bloc/auth_bloc.dart';
import 'features/auth/presentation/bloc/auth_event.dart';
void main() async {
// ...
final authBloc = sl<AuthBloc>();
authBloc.add(AuthStarted());
runApp(LinksyApp(authBloc: authBloc));
}
问题
-
启动逻辑与认证模块耦合
- main.dart 需要知道
AuthBloc的存在 - 需要知道
AuthStarted事件 - 需要手动触发启动事件
- main.dart 需要知道
-
AuthBloc 被暴露3层
main.dart → LinksyApp → createAppRouter → redirect()每层都传 authBloc,不优雅
建议方案
1. 启动逻辑下沉到 LinksyApp
// main.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await configureDependencies();
await AppConstants.init();
runApp(LinksyApp());
}
// app.dart (LinksyApp)
class LinksyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final authBloc = sl<AuthBloc>();
authBloc.add(AuthStarted());
return BlocProvider.value(
value: authBloc,
child: // ...
);
}
}
2. 路由守卫由 LinksyApp 内部管理
// app.dart
class LinksyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocListener<AuthBloc, AuthState>(
listener: (context, state) {
final router = GoRouter.of(context);
if (state is AuthUnauthenticated) {
router.go(AppRoutes.authLogin);
} else if (state is AuthAuthenticated) {
if (router.matchedLocation == AppRoutes.authLogin) {
router.go(AppRoutes.homeMain);
}
}
},
child: MaterialApp.router(
routerConfig: createAppRouter(),
),
);
}
}
3. createAppRouter 不再需要 authBloc 参数
// app_router.dart
GoRouter createAppRouter() {
return GoRouter(
// 不再有 redirect 回调
// 路由守卫由 BlocListener 在 LinksyApp 统一处理
);
}
收益
| 收益 | 说明 |
|---|---|
| 解耦 | main.dart 完全不知道 AuthBloc 存在 |
| 单一职责 | LinksyApp 统一管理状态监听和路由跳转 |
| 易测试 | main.dart 不再需要 mock AuthBloc |
涉及文件
apps/lib/main.dartapps/lib/app/app.dartapps/lib/app/router/app_router.dartapps/lib/features/auth/presentation/bloc/auth_bloc.dart
状态
- 待修复