繁体   English   中英

无法在使用可注入和 get_it 包时注册抽象类

[英]unable to register an abstract class in using injectable and get_it packages

我在flutter dart中使用injectable和get_it(遵循非常流行的Reso coder

我有一个简单的抽象类:

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);
}

最后,我有一个 injection.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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM