我在我的 flutter 项目中使用 get_it 进行依赖注入。 现在我尝试使用可注入来用注释替换我的手写依赖文件。
我有一个特殊情况,我有一个通用类,必须使用不同的 T 值注入 3 次。
class TestBloc<T> {
...
}
这就是我旧配置中的样子:
sl.registerFactory(() => TestBloc<One>(...);
sl.registerFactory(() => TestBloc<Two>(...);
sl.registerFactory(() => TestBloc<Three>(...);
如何对课程进行注释才能使其发挥作用?
当我添加@injectable
@injectable
class TestBloc<T> {
...
}
我明白了(当然):
gh.factory<_i34.TestBloc<dynamic>>(() =>_i34.TestBloc<dynamic>(...);
如何注释才能得到这个?
gh.factory<_i34.TestBloc<One>>(() =>_i34.TestBloc<One>(...);
gh.factory<_i34.TestBloc<Two>>(() =>_i34.TestBloc<Two>(...);
gh.factory<_i34.TestBloc<Three>>(() =>_i34.TestBloc<Three>(...);
我遇到了同样的问题,我想出的解决方案可以解决问题。您必须为具有通用类型的视图模型创建一个工厂。在里面您可以请求您需要的所有泛型类型的依赖项。不幸的是,您必须手动构建所有依赖项。但本质上它与绑定相同。接下来,您必须为您的特定类型扩展工厂。这将确保填充所有必需的类型。然后编译器可以搜索这些类型。美妙之处在于,对于您类型的每个变体,您都可以覆盖一些绑定。如果你真的想要,你还可以提供工厂的不同实现。 小例子:
abstract class StdOutUseCase<T> {
void printEmpty();
}
mixin Arbitrary<T> {
T call(Random random);
}
mixin Empty<T> {
T call();
}
class MockViewModel<T> {
final StdOutUseCase<T> stdOutUseCase;
MockViewModel(this.stdOutUseCase);
void onButtonClick() {
stdOutUseCase.printEmpty();
}
}
@Injectable(as: Empty<String>)
class StringEmpty with Empty<String> {
@override
String call() {
return "";
}
}
@Injectable(as: Arbitrary<String>)
class ArbString with Arbitrary<String> {
static const adjectives = ["happy", "smart", "cool", "cold"];
static const nouns = ["fox", "bear", "gorilla"];
@override
String call(Random random) {
return "${adjectives[random.nextInt(adjectives.length)]} ${nouns[random.nextInt(nouns.length)]}";
}
}
@Injectable(as: Factory<MockViewModel<String>>)
class StringFactory extends MockVMFactory<String> {
StringFactory(super.empty, super.arbitrary);
}
mixin Factory<T>{
T call();
}
class MockVMFactory<T> with Factory<MockViewModel<T>> {
final Empty<T> empty;
final Arbitrary<T> arbitrary;
MockVMFactory(this.empty, this.arbitrary);
@override
MockViewModel<T> call() => MockViewModel(useCase());
StdOutUseCase<T> useCase() => FancyStdOutUseCase(empty, arbitrary);
}
class FancyStdOutUseCase<T> extends StdOutUseCase<T> {
final Empty<T> empty;
final Arbitrary<T> arbitrary;
FancyStdOutUseCase(this.empty, this.arbitrary);
@override
void printEmpty() {
print("Empty is ${empty()} and random is ${arbitrary(Random())}");
}
}
class BaseStdOutUseCase<T> extends StdOutUseCase<T> {
final Empty<T> empty;
@inject
BaseStdOutUseCase(this.empty);
@override
void printEmpty() {
print("Empty for $T is ${empty()}");
}
}