GetIt无法正确找到基于抽象类/接口的注册类型,但成功找到了具体类



上下文

我正在使用:

  • Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-US)
  • CCD_ 2

我有以下注入器,它包括CategoryRepositoryAdapter服务(实现CategoryRepositoryPort):

// injector.dart
final injector = GetIt.instance;
Future<void> initializeDependencies() async {
// Rest Client
injector.registerSingleton<Dio>(Dio());
// Database Client
final database = await $FloorMoneyDatabase
.databaseBuilder(kDatabaseName)
.build();
injector.registerSingleton<MoneyDatabase>(database);
// Database Mappers and Repositories
injector.registerSingleton<CategoryEntityMapper>(
CategoryEntityMapper()
);
injector.registerSingleton<CategoryRepositoryPort>(    // <--- problem is here
CategoryRepositoryAdapter(injector(), injector())
);
// UI Handlers
injector.registerSingleton<CategoryHandlerPort>(
CategoryHandler(injector())
);
// Blocs
injector.registerFactory<LocalCategoryBloc>(
() => LocalCategoryBloc(injector())
);
}

调用该服务的类如下所示:

// category.handler.dart
class CategoryHandler implements CategoryHandlerPort {
final CategoryRepositoryPort _repository;  // <--- problem is here
const CategoryHandler(this._repository);
Stream<Category?> findAllCategories() {
...
}
Future<Category?> findCategoryById(int id) {
...
}
...
}

要注入的具体服务如下所示:

// category.repository_adapter.dart
class CategoryRepositoryAdapter implements CategoryRepositoryPort {
final MoneyDatabase _database;
final CategoryEntityMapper _map;
const CategoryRepositoryAdapter(this._database, this._map);
@override
Stream<Category> findAllCategories() async* {
...
}
@override
Future<Category?> findCategoryById(int id) async {
...
}
@override
Future<void> insertCategory(Category category) {
...
}
@override
Future<void> removeCategory(Category category) {
...
}
}

错误

当我用上面的方法运行应用程序时,我会得到错误:

Object/factory with  type CategoryRepositoryAdapter is not registered inside GetIt. 
(Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;
Did you forget to register it?)

解决方案

如果我注册具体类CategoryRepositoryAdapter,而不是它实现的抽象类CategoryRepositoryPort,并在调用类中引用前者,那么一切都很好:

// injector.dart
...
injector.registerSingleton<CategoryRepositoryAdapter>(    // <-- changed this to point to concrete class
CategoryRepositoryAdapter(injector(), injector())
);
...
// category.handler.dart
class CategoryHandler implements CategoryHandlerPort {
final CategoryRepositoryAdapter _repository;    // <-- changed this to point to concrete class
const CategoryHandler(this._repository);
...

摘要

  • get_it在使用具体类时成功注册服务
  • get_it在使用抽象类时没有注册服务

有什么线索吗?

已解决。环顾四周,我发现我在其他地方称混凝土类为CategoryRepositoryAdapter;使CCD_ 10产生混淆。

到处调用抽象类CategoryRepositoryPort解决了这个问题