GetIt 无法根据抽象 class/interface 正确找到注册类型,但使用具体 class 成功
GetIt not being able to correctly find registered type based on abstract class/interface, but succeeds with concrete class
上下文
我正在使用:
Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-US)
get_it: ^7.2.0
.
我有以下注入器,其中包括 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())
);
}
调用该服务的 class 如下所示:
// 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?)
解决方法
如果我注册具体 class、CategoryRepositoryAdapter
,而不是它实现的抽象 class CategoryRepositoryPort
,并在调用 class,一切正常:
// 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
使用具体 class; 时注册服务成功
get_it
在使用摘要 class 时未注册服务。
有什么线索可能是错的吗?
已解决。环顾四周,我发现我在其他地方调用了具体的class CategoryRepositoryAdapter
;这让 get_it
感到困惑。
到处调用摘要classCategoryRepositoryPort
解决了。
上下文
我正在使用:
Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-US)
get_it: ^7.2.0
.
我有以下注入器,其中包括 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())
);
}
调用该服务的 class 如下所示:
// 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?)
解决方法
如果我注册具体 class、CategoryRepositoryAdapter
,而不是它实现的抽象 class CategoryRepositoryPort
,并在调用 class,一切正常:
// 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
使用具体 class; 时注册服务成功
get_it
在使用摘要 class 时未注册服务。
有什么线索可能是错的吗?
已解决。环顾四周,我发现我在其他地方调用了具体的class CategoryRepositoryAdapter
;这让 get_it
感到困惑。
到处调用摘要classCategoryRepositoryPort
解决了。