【问题标题】:Riverpod - Create service with async dependency better/elegant wayRiverpod - 以更好/优雅的方式创建具有异步依赖的服务
【发布时间】:2021-06-28 21:32:38
【问题描述】:

我编写了一些代码,将ApiService 提供给StateNotifierApiService 依赖于 authenticatorclient - 身份验证客户端必须异步创建,因为它使用 sharedprefs 获取令牌。

我只是想弄清楚他们的写作方式是否更优雅。基本上,当服务 apiService 被注入到 StateNotifier 中时,它可能是可以为空的......对我来说这有点代码味道。

简而言之,这就是我正在做的事情...... 使用FutureProvider 实例化RestClientDio

authenticatorClient = FutureProvider<RestClient>((ref) async {
  final prefs = await SharedPreferences.getInstance();
  final dio = Dio();
  ...
  return RestClient(dio);
}

然后我观看并使用 MaybeWhen 来返回服务

final clientCreatorWatchProvider = Provider<ApiService?>((ref) => ref
    .watch(authenticatorClient)
    .whenData((value) => ApiService(value))
    .maybeWhen(
      data: (service) => service,
      orElse: () => null,
    ));

所以我不喜欢的一点是 orElse 返回 null

然后我的StateNotifier 正在观看...

final AppState = StateNotifierProvider<AppNotifier, String>(
    (ref) => AppNotifier(ref.watch(clientCreatorWatchProvider)));

class AppNotifier extends StateNotifier<String> {
  final ApiService? apiService;

  AppNotifier(this.apiService) : super("loading") {
    init();
  }
...
}

对上述方法有什么想法吗?

谢谢

【问题讨论】:

    标签: flutter riverpod


    【解决方案1】:

    解决此问题的一种方法是在提供程序之外初始化SharedPreferences。然后,您可以使用 ProviderScope 覆盖同步提供程序,从而无需使用 AsyncValue

    初始化应用时,请执行以下操作:

    final sharedPreferences = Provider<SharedPreferences>((_) => throw UnimplementedError());
    
    Future<void> main() async {
      final sharedPrefs = await SharedPreferences.getInstance();
    
      runApp(
        ProviderScope(
          overrides: [
            sharedPreferences.overrideWithValue(sharedPrefs),
          ],
          child: MyApp(),
        ),
      );
    }
    

    现在您可以像这样编写您的提供程序:

    final authenticatorClient = Provider<RestClient>((ref) {
      final prefs = ref.watch(sharedPreferences);
      final dio = Dio();
      ...
      return RestClient(dio);
    }
    
    final clientCreatorWatchProvider = Provider<ApiService>((ref) {
      final authClient = ref.watch(authenticatorClient);
      return ApiService(authClient);
    });
    

    【讨论】:

    • 这真的有效吗?请参阅 github.com/rrousselGit/river_pod/issues/575 关于提供程序监视其他提供程序但未获得覆盖值的信息。
    • @wujek 对于这种情况,是的。我避免在根应用程序之外使用 ProviderScope,就像在这个例子中一样,所以我不能谈论其他情况。
    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-23
    • 2013-08-24
    相关资源
    最近更新 更多