我在flutter dart中使用injectable和get_it(遵循非常流行的Reso编码器)
我有一个简单的抽象类:import 'package:injectable/injectable.dart';
//@injectable
abstract class IRandomQuantityRepository {
Future<int> getRandomQuantity();
}
,我有两个简单的具体实现:
import 'package:injectable/injectable.dart';
@dev
@injectable
class DevRandomQuantityRepository implements IRandomQuantityRepository {
const DevRandomQuantityRepository();
@override
Future<int> getRandomQuantity() async => 90;
}
和
import 'dart:math';
import 'package:injectable/injectable.dart';
@prod
@injectable
class RandomQuantityRepository implements IRandomQuantityRepository {
const RandomQuantityRepository();
@override
Future<int> getRandomQuantity() async => Random().nextInt(100);
}
最后,我要注射。dart:
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'package:moontreeapp/injection.config.dart';
final GetIt getIt = GetIt.instance;
@InjectableInit(preferRelativeImports: false)
void configureInjection(String env) {
$initGetIt(getIt, environment: env);
}
abstract class Env {
static const prod = 'prod';
static const dev = 'dev';
}
除此之外,我还有一个集团想要使用的东西:
@injectable
class RandomQuantityBloc
extends Bloc<RandomQuantityEvent, RandomQuantityState> {
final IRandomQuantityRepository _quantityFacade; // notice this final...
看起来不错吧?我想是的。然后我运行这个命令使生成的代码flutter pub run build_runner watch
但我得到一个消息:
[RandomQuantityBloc]依赖于未注册的类型[IRandomQuantityRepository]…您是否忘记用@injectable注释上述类或它们的实现?或者添加正确的环境键?
好,这很酷,让我们把它添加到接口:
import 'package:injectable/injectable.dart';
@injectable // <-- added
abstract class IRandomQuantityRepository {
Future<int> getRandomQuantity();
}
但是我得到一个新的错误:
> [IRandomQuantityRepository] is abstract and can not be registered directly!
> if it has a factory or a create method annotate it with @factoryMethod
> 14 │ abstract class IRandomQuantityRepository {
> │ ^^^^^^^^^^^^^^^^^^^^^^^^^
在过去,我手动处理依赖注入,所以我是这些包的新手,我在这里错过了什么?
除此之外,真正的问题是我不能根据环境切换注入。我可以使用get_it来获取具体的依赖项,但不能像下面这个测试那样基于环境:
/// has no effect:
configureInjection(Env.dev);
/// gets prod version:
final devRandomQuantity = getIt<RandomQuantityRepository>();
所以关于整个设置的某些东西没有正确配置注入…我错过了什么?
最后一件可能有用的事情是查看生成的代码:// GENERATED CODE - DO NOT MODIFY BY HAND
// **************************************************************************
// InjectableConfigGenerator
// **************************************************************************
import 'package:get_it/get_it.dart' as _i1;
import 'package:injectable/injectable.dart' as _i2;
import 'package:moontreeapp/application/quantity/bloc/randomquantity_bloc.dart'
as _i5;
import 'package:moontreeapp/domain/quantity/i_randomquantity_repository.dart' as _i6;
import 'package:moontreeapp/infrastructure/quantity/dev_randomquantity_repository.dart'
as _i3;
import 'package:moontreeapp/infrastructure/quantity/mock_randomquantity_repository.dart'
as _i4;
import 'package:moontreeapp/infrastructure/quantity/randomquantity_repository.dart'
as _i7;
const String _dev = 'dev';
const String _prod = 'prod';
// ignore_for_file: unnecessary_lambdas
// ignore_for_file: lines_longer_than_80_chars
/// initializes the registration of provided dependencies inside of [GetIt]
_i1.GetIt $initGetIt(_i1.GetIt get,
{String? environment, _i2.EnvironmentFilter? environmentFilter}) {
final gh = _i2.GetItHelper(get, environment, environmentFilter);
gh.factory<_i3.DevRandomQuantityRepository>(
() => _i3.DevRandomQuantityRepository(),
registerFor: {_dev});
gh.factory<_i5.RandomQuantityBloc>(
() => _i5.RandomQuantityBloc(get<_i6.IRandomQuantityRepository>()));
gh.factory<_i7.RandomQuantityRepository>(() => _i7.RandomQuantityRepository(),
registerFor: {_prod});
return get;
}
我是否把@injectable放在抽象类上?
好的,所以我猜injectable看不到类实现了什么,所以你必须让它显式。还有,@dev不是内置的,你必须自己创建。
所以这是正确使用装饰的方法
@Environment('dev')
@Injectable(as: IRandomQuantityRepository)
class DevRandomQuantityRepository implements IRandomQuantityRepository {
const DevRandomQuantityRepository();
@override
Future<Either<QuantFailure, Quantity>> getRandomQuantity() async =>
right(Quantity(Amount(900.0001), Decimal(4)));
}
这样就可以了:
configureInjection(Env.dev);
final mockRandomQuantity = getIt<IRandomQuantityRepository>();
await mockRandomQuantity.getRandomQuantity();
// 90