Injectable环境下MovieWatcherBloc依赖未注册StreamSubscription报错
解决依赖注册问题的方案
问题根源
你在MovieWatcherBloc的构造函数中把StreamSubscription声明为依赖参数,要求Injectable为你注入这个对象,但StreamSubscription是动态创建的订阅对象,不属于需要依赖注入的服务/仓库类,Injectable无法注册也不应该管理它。
修改步骤
- 移除构造函数中的
StreamSubscription参数,将其改为Bloc内部的成员变量,自行初始化和管理。 - 调整订阅逻辑:首次订阅前不需要执行
cancel(初始状态下订阅对象为null),避免空指针异常。 - 安全处理订阅销毁:在
close方法中先判断订阅是否存在,再执行cancel。
修改后的完整代码
import 'dart:async'; import 'package:app_3/Domain/auth/notes/i_movie_repository.dart'; import 'package:app_3/Domain/auth/notes/list.dart'; import 'package:app_3/Domain/auth/notes/note_failure.dart'; import 'package:bloc/bloc.dart'; import 'package:dartz/dartz.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart'; import 'package:kt_dart/kt.dart'; part 'movie_watcher_event.dart'; part 'movie_watcher_state.dart'; part 'movie_watcher_bloc.freezed.dart'; @injectable class MovieWatcherBloc extends Bloc<MovieWatcherEvent, MovieWatcherState> { final INoteRepository _noteRepository; // 改为内部成员变量,初始为null StreamSubscription<Either<NoteFailure, KtList<Mlist>>>? _noteStreamSubscription; // 构造函数只保留仓库依赖 MovieWatcherBloc(this._noteRepository) : super(const MovieWatcherState.initial()) { @override Stream<MovieWatcherState> mapEventToState( MovieWatcherEvent event, ) async* { yield* event.map(watchAllstarted: (e) async* { yield const MovieWatcherState.loadInProgress(); // 先判断订阅是否存在,再取消 await _noteStreamSubscription?.cancel(); // 创建新的订阅 _noteStreamSubscription = _noteRepository.watchAll().listen( (failureOrNotes) => add(MovieWatcherEvent.moviesReceived(failureOrNotes)), ); }, watchUncompletedstarted: (e) async* { yield const MovieWatcherState.loadInProgress(); await _noteStreamSubscription?.cancel(); _noteStreamSubscription = _noteRepository.watchUncompleted().listen( (failureOrNotes) => add(MovieWatcherEvent.moviesReceived(failureOrNotes)), ); }, moviesReceived: (e) async* { yield e.failureOrNotes.fold( (f) => MovieWatcherState.loadFailure(f), (lists) => MovieWatcherState.loadSuccess(lists), ); }); } } @override Future<void> close() async { // 安全取消订阅 await _noteStreamSubscription?.cancel(); return super.close(); } }
后续验证
- 重新运行
build_runner:
flutter pub run build_runner watch --delete-conflicting-outputs
此时之前的依赖未注册警告会消失。
2. 运行应用,GetIt找不到对象的错误也会解决。
内容的提问来源于stack exchange,提问作者nidhin ninan
相关产品推荐
相关产品推荐

