如何在flutter中使用injectable和get_it的共享偏好?

ali*_*oor 5 dependency-injection injectable sharedpreferences flutter flutter-dependencies

我在flutter中使用了injectable和get_it包,我有一个共享的首选项类:

@LazySingleton()
class SharedPref {
  final String _token = 'token';
  SharedPreferences _pref;

  SharedPref(this._pref);

  Future<String> getToken() async {
    return _pref.getString(_token) ?? '';
  }

  Future<void> setToken(String token) async {
    await _pref.setString(_token, token);
  }
}

Run Code Online (Sandbox Code Playgroud)

这个类作为LazySingleton注入,我有一个模块用于注入共享首选项:

@module
abstract class InjectableModule {

 @lazySingleton
 Future<SharedPreferences> get prefs => SharedPreferences.getInstance();
}

Run Code Online (Sandbox Code Playgroud)

在集团类 im 中使用 SharedPref 类:

@injectable
class LoginCheckBloc extends Bloc<LoginCheckEvent, LoginCheckState> {
  final SharedPref sharedPref;

  LoginCheckBloc({@required this.sharedPref}) : super(const LoginCheckState.initial());

  @override
  Stream<LoginCheckState> mapEventToState(
    LoginCheckEvent event,
  ) async* {
    if (event is CheckLogin) {
      final String token = await sharedPref.getToken();
      if (token.isEmpty){
        yield const LoginCheckState.notLogin();
      }else{
        yield const LoginCheckState.successLogin();
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当我将 LoginCheckBloc 与 getIt<> 一起使用时,我在注入共享偏好时出现错误:

BlocProvider<LoginCheckBloc>(
          create: (BuildContext context) => getIt<LoginCheckBloc>()..add(CheckLogin()),
        ),
Run Code Online (Sandbox Code Playgroud)

错误信息是:

You tried to access an instance of SharedPreferences that was not ready yet
'package:get_it/get_it_impl.dart':
Failed assertion: line 272 pos 14: 'instanceFactory.isReady'

Run Code Online (Sandbox Code Playgroud)

如何使用可注射的共享偏好?

Dav*_*ing 8

它的工作对我的,当我用@preResolveSharedPreference

@module
abstract class InjectableModule{

@preResolve
Future<SharedPreferences> get prefs => SharedPreferences.getInstance();
}
Run Code Online (Sandbox Code Playgroud)

然后在可注入的类上你写这个

final GetIt getIt = GetIt.instance;

@injectableInit
Future<void> configureInjection(String env) async {
await $initGetIt(getIt, environment: env);
}
Run Code Online (Sandbox Code Playgroud)

和在主课上

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await configureInjection(Environment.prod);
runApp(MyApp());
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我能够通过包装来解决它runApp()GetIt.I.isReady<SharedPreferences>()

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  GetIt.I.isReady<SharedPreferences>().then((_) {
    runApp(MyApp());
  });
}
Run Code Online (Sandbox Code Playgroud)