You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:35:28