Flutter Clean Architecture中跨Feature共享实体的实现方案问询
项目背景
我正在开发一个采用Bloc状态管理、get_it依赖注入的Flutter Clean Architecture小型应用。目前已实现一个登录Feature,可向API发起请求并将返回信息映射为Model,随后通过Bloc Builder的State以Entity形式访问。
相关代码片段
Presentation层Entity赋值代码
static LoginEntity? loginEntity = const LoginEntity(); loginEntity = state.loginEntity![0];
Bloc State定义
abstract class RemoteLoginDetailsState extends Equatable { const RemoteLoginDetailsState({this.loginEntity}); @override List<Object?> get props => [loginEntity!]; }
API请求与Model映射代码
LoginModel value = LoginModel.fromJson(_result.data!); final httpResponse = HttpResponse([value], _result); return httpResponse;
核心疑问
如何在符合Clean Architecture规范的前提下,将一个Feature中API返回的实体信息共享给其他Feature使用?比如登录Feature获取到name字段并映射到Model后,如何在其他Feature中合规访问该字段的值?
我了解可能通过传递State实现,但不确定是否符合Clean Architecture,也不清楚具体实现方式;也知道DTO的存在,但认为DTO仅适用于同一Feature内的数据传输。
合规解决方案
1. 抽离共享Entity到核心层
Clean Architecture的核心规则是所有Feature依赖最底层的核心层,不要把LoginEntity放在登录Feature内部,而是抽离到项目根目录的core/entities文件夹下。这样所有Feature都可以直接引用这个Entity,保证数据模型的一致性,同时避免Feature间的直接依赖。
2. 全局状态管理方案
方案一:全局Bloc
创建不属于某个Feature的全局UserBloc,登录成功后将LoginEntity数据提交到该Bloc的State中,其他Feature通过监听这个全局Bloc获取用户信息:
// 全局UserBloc定义 class UserBloc extends Bloc<UserEvent, UserState> { UserBloc() : super(UserInitial()) { on<SetUserEvent>((event, emit) => emit(UserLoaded(event.user))); } } // 登录Feature成功后触发事件 context.read<UserBloc>().add(SetUserEvent(loginEntity)); // 其他Feature中监听获取 BlocBuilder<UserBloc, UserState>( builder: (context, state) { if (state is UserLoaded) { return Text(state.user.name); } return const SizedBox(); }, )
方案二:全局单例服务
通过get_it注册一个全局UserService,内部持有用户状态,登录成功后更新状态,其他Feature直接从服务读取数据:
// 全局UserService定义 class UserService { LoginEntity? _currentUser; LoginEntity? get currentUser => _currentUser; void setUser(LoginEntity user) { _currentUser = user; } } // 注册到get_it getIt.registerSingleton<UserService>(UserService()); // 登录成功后更新 getIt<UserService>().setUser(loginEntity); // 其他Feature中获取 final currentUser = getIt<UserService>().currentUser;
3. 避坑提醒
不要直接从登录Feature的Bloc State中传递数据到其他Feature,这会造成Feature间的强耦合,违反Clean Architecture的依赖倒置原则。DTO确实仅用于同一Feature内的层间数据传输,跨Feature共享必须依赖核心层的Entity。
内容的提问来源于stack exchange,提问作者RJASSI98

