Flutter中如何用getIt/injectable通过ID获取同一BookmarkCubit实例?
在GetIt中实现类似Riverpod Family的参数化单例(针对BookmarkCubit)
要实现同一帖子ID对应同一个BookmarkCubit实例(跨页面同步状态),核心是让GetIt根据帖子ID作为标识来区分和复用实例,替代默认仅按类型区分的逻辑。以下是具体实现方案:
1. 正确注册参数化的BookmarkCubit
使用GetIt的registerLazySingletonParam方法,它支持传入参数并根据参数生成唯一的实例标识(通过instanceName),确保同一帖子ID返回同一个Cubit单例:
void setupDependencyInjection() { // 先注册依赖的Repository(如果有) GetIt.I.registerLazySingleton<BookmarkRepository>(() => BookmarkRepositoryImpl()); // 注册带参数的BookmarkCubit,用postId作为instanceName GetIt.I.registerLazySingletonParam<BookmarkCubit, String>( (postId) => BookmarkCubit( postId, GetIt.I.get<BookmarkRepository>(), // 注入依赖的Repository ), // 用postId作为实例名称,确保同一postId对应同一实例 instanceName: (postId) => postId, ); }
2. 跨页面获取同一实例
在任意页面需要获取对应帖子的BookmarkCubit时,通过指定instanceName为帖子ID,即可拿到同一个实例:
// 在页面中获取指定帖子的BookmarkCubit final post = // 当前展示的帖子对象 final bookmarkCubit = GetIt.I.get<BookmarkCubit>(instanceName: post.id);
此时,无论在哪个页面调用上述代码,只要post.id相同,都会返回同一个BookmarkCubit实例,状态更新会自动同步到所有监听该实例的页面。
3. 内存优化:注销不再需要的实例
当帖子页面销毁后,可主动注销对应的BookmarkCubit实例避免内存泄漏:
@override void dispose() { GetIt.I.unregister<BookmarkCubit>(instanceName: post.id); super.dispose(); }
为什么你之前的调用会创建新实例?
你之前使用GetIt.instance<BookmarkCubit>(param1: post.id)生成新实例,大概率是因为注册时用了registerFactoryParam——这个方法每次调用都会生成新实例,而registerLazySingletonParam才会对同一参数复用已创建的单例,这和Riverpod Family的行为一致。
内容的提问来源于stack exchange,提问作者Kimiya Zargari
相关产品推荐
相关产品推荐

