如何在无Ref的Repository类中通过Provider获取LocalUser信息
优化方案:在Riverpod中优雅获取LocalUser实现位置发送
你当前在ChatMessagingRepository中手动实例化LocalUserProfileRepo的做法不符合Riverpod依赖注入的设计理念,且不利于代码维护和测试,以下是几种更优的实现方案:
方案1:给ChatMessagingRepository注入WidgetRef
让Repository持有Riverpod的Ref实例,从而通过Provider体系获取依赖,避免手动实例化。
修改Repository代码
class ChatMessagingRepository { final WidgetRef ref; // 构造函数注入Ref ChatMessagingRepository(this.ref); Future<void> sendLocation() async { // 通过ref获取LocalUserProfileRepo实例 final localUserRepo = ref.read(localUserProfileRepoProvider); final localUser = await localUserRepo.getlLocalUser(); // ... 执行发送位置的业务逻辑 } }
更新Provider定义
final chatMessagingRepositoryProvider = Provider<ChatMessagingRepository>((ref) { // 将Provider自身的ref传递给Repository return ChatMessagingRepository(ref); });
优点:Repository可自主管理依赖,UI层无需关心内部逻辑;完全遵循依赖注入原则,代码解耦性更强。
方案2:UI层获取LocalUser后传递给sendLocation
让Repository保持单一职责,仅负责发送逻辑,所需依赖由上层UI传入。
修改Repository方法
class ChatMessagingRepository { Future<void> sendLocation(UserProfile localUser) async { // 直接使用传入的localUser执行发送逻辑 // ... } }
更新UI层调用逻辑
InkWell( key: WidgetKey.location, onTap: () async { // 在UI层通过ref获取LocalUser final localUserRepo = ref.read(localUserProfileRepoProvider); final localUser = await localUserRepo.getlLocalUser(); // 将localUser作为参数传入sendLocation await ref.read(chatMessagingRepositoryProvider).sendLocation(localUser); }, child: MyIcons.chatPin )
优点:Repository无需依赖Ref,职责更纯粹;测试时可直接传入模拟的UserProfile,单元测试更简单。
方案3:将LocalUser封装为FutureProvider
如果LocalUser是应用中频繁使用的数据,可将其封装为FutureProvider,实现数据缓存,避免重复请求数据库。
定义LocalUser的FutureProvider
final localUserProvider = FutureProvider<UserProfile>((ref) async { final localUserRepo = ref.read(localUserProfileRepoProvider); return localUserRepo.getlLocalUser(); });
在Repository中使用(需结合方案1注入Ref)
Future<void> sendLocation() async { // 直接读取缓存的LocalUser,无需重复调用getlLocalUser final localUser = await ref.read(localUserProvider.future); // ... 执行发送逻辑 }
或在UI层读取后传递(需处理异步状态)
@override Widget build(BuildContext context, WidgetRef ref) { final localUserAsync = ref.watch(localUserProvider); return localUserAsync.when( data: (localUser) => InkWell( key: WidgetKey.location, onTap: () => ref.read(chatMessagingRepositoryProvider).sendLocation(localUser), child: MyIcons.chatPin ), loading: () => const CircularProgressIndicator(), error: (_, __) => const Icon(Icons.error_outline) ); }
优点:缓存LocalUser数据,减少重复数据库请求;统一管理LocalUser的获取逻辑,提升代码复用性。
内容的提问来源于stack exchange,提问作者Timm Kent
相关产品推荐
相关产品推荐

