无法使用 Get_it 在颤振中初始化 GraphQl 客户端

时间:2021-06-25 04:28:54

标签: flutter graphql service-locator

我想在我的 Flutter 应用程序中实现 GraphQL 客户端。对于依赖注入,我使用 GetIt 库。但是当我运行应用程序时,它说

<块引用>

'无效参数(HomeGraphQLService 类型的对象不是 在 GetIt 内注册。您是否忘记传递实例名称? (你是不是不小心做了 GetIt sl=GetIt.instance(); 而不是 GetIt sl=GetIt.instance;)): HomeGraphQLService'

.

这意味着 GraphQL 客户端没有以某种方式实例化,尽管我在我的服务定位器中注册了它

Session.dart

abstract class Session {
  String getAccessToken();
}

SessionImpl.dart

class SessionImpl extends Session {
  SharedPreferences sharedPref;

  SessionImpl(SharedPreferences sharedPref) {
    this.sharedPref = sharedPref;
  }

  @override
  String getAccessToken() {
    return sharedPref.getString('access_token') ?? "";
  }

}

GraphQLClientGenerator.dart

class GraphQLClientGenerator {
  Session session;

  GraphQLClientGenerator(Session session) {
    this.session = session;
  }

  GraphQLClient getClient() {
    final HttpLink httpLink = HttpLink('https://xxx/graphql');
    final AuthLink authLink = AuthLink(getToken: () async => 'Bearer ${_getAccessToken()}');
    final Link link = authLink.concat(httpLink);

    return GraphQLClient(link: link, cache: GraphQLCache(store: InMemoryStore()));
  }

  String _getAccessToken() {
    return session.getAccessToken();
  }
}

HomeRepository.dart

abstract class HomeRepository {
  Future<List<Course>> getAllCourseOf(String className, String groupName);
}

HomeRepositoryImpl.dart

class HomeRepositoryImpl extends HomeRepository {

  HomeGraphQLService homeGraphQLService;
  HomeMapper homeMapper;

  HomeRepositoryImpl(HomeGraphQLService homeGraphQLService, HomeMapper homeMapper) {
    this.homeGraphQLService = homeGraphQLService;
    this.homeMapper = homeMapper;
  }

  @override
  Future<List<Course>> getAllCourseOf(String className, String groupName) async {
    final response = await homeGraphQLService.getAllCourseOf(className, groupName);
    return homeMapper.toCourses(response).where((course) => course.isAvailable);
  }

}

HomeGraphQLService.dart

class HomeGraphQLService {
  GraphQLClient graphQLClient;

  HomeGraphQLService(GraphQLClient graphQLClient) {
    this.graphQLClient = graphQLClient;
  }

  Future<SubjectResponse> getAllCourseOf(String className, String groupName) async {
    try {
      final response = await graphQLClient.query(getAllCourseQuery(className, groupName));
      return SubjectResponse.fromJson((response.data));
    }  catch (e) {
      return Future.error(e);
    }
  }
}

GraphQuery.dart

QueryOptions getAllCourseQuery(String className, String groupName) {
  String query = """
    query GetSubject($className: String, $groupName: String) {
      subjects(class: $className, group: $groupName) {
        code
        display
        insights {
          coming_soon
          purchased
        }
      }
    }
    """;

  return QueryOptions(
    document: gql(query),
    variables: <String, dynamic>{
      'className': className,
      'groupName': groupName,
    },
  );
}

ServiceLocator.dart

final serviceLocator = GetIt.instance;

Future<void> initDependencies() async {
  await _initSharedPref();
  _initSession();
  _initGraphQLClient();
  _initGraphQLService();
  _initMapper();
  _initRepository();
}

Future<void> _initSharedPref() async {
  SharedPreferences sharedPref = await SharedPreferences.getInstance();
  serviceLocator.registerSingleton<SharedPreferences>(sharedPref);
}

void _initSession() {
  serviceLocator.registerLazySingleton<Session>(()=>SessionImpl(serviceLocator()));
}

void _initGraphQLClient() {
  serviceLocator.registerLazySingleton<GraphQLClient>(() => GraphQLClientGenerator(serviceLocator()).getClient());
}

void _initGraphQLService() {
  serviceLocator.registerLazySingleton<HomeGraphQLService>(() => HomeGraphQLService(serviceLocator()));
}

void _initMapper() {
  serviceLocator.registerLazySingleton<HomeMapper>(() => HomeMapper());
}

void _initRepository() {
  serviceLocator.registerLazySingleton<HomeRepository>(() => HomeRepositoryImpl(serviceLocator(), serviceLocator()));
}

main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  SystemChrome.setPreferredOrientations(
    [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
  );
  
  await initDependencies();

  runApp(MyApp());
}

1 个答案:

答案 0 :(得分:1)

我无法说出它究竟发生在哪里,因为它在您访问 GraphQLService 的代码中的其他地方,但问题肯定是由于延迟加载造成的。在访问对象之前,locator 尚未创建和加载该对象。尝试更新 ServiceLocator.dart 以在注册期间实例化类,如下所示:

void _initSession() {
  serviceLocator.registerSingleton<Session>.(SessionImpl(serviceLocator()));
}

void _initGraphQLClient() {
  serviceLocator.registerSingleton<GraphQLClient>(
    GraphQLClientGenerator(serviceLocator()).getClient());
}

void _initGraphQLService() {
  serviceLocator.registerSingleton<HomeGraphQLService>(
    HomeGraphQLService(serviceLocator()));
}

void _initMapper() {
  serviceLocator.registerSingleton<HomeMapper>(HomeMapper());
}

void _initRepository() {
  serviceLocator.registerSingleton<HomeRepository>(
    HomeRepositoryImpl(serviceLocator(), serviceLocator()));
}