如何在运行时以编程方式扫描Flutter项目中实现特定抽象类的类?
在Flutter运行时扫描实现特定抽象类的类列表
Flutter默认禁用了Dart的动态反射,你可以通过以下几种方式实现需求:
1. 用reflectable包实现反射扫描
这是最常用的反射方案,依赖编译时生成的反射代码:
- 先在
pubspec.yaml里添加依赖:dependencies: reflectable: ^4.0.0 dev_dependencies: build_runner: ^2.4.6 - 创建反射配置类,定义扫描能力:
import 'package:reflectable/reflectable.dart'; class Scanable extends Reflectable { const Scanable() : super( typeCapability, subtypeQuantifyCapability, ); } const scanable = Scanable(); - 给**所有需要被扫描的类(包括抽象类和实现类)**加上
@scanable注解:@scanable abstract class MyAbstractClass {} @scanable class ConcreteClassA extends MyAbstractClass {} @scanable class ConcreteClassB extends MyAbstractClass {} - 运行命令生成反射代码:
dart run build_runner build - 编写扫描逻辑,筛选出抽象类的实现类:
注意:没加List<Type> findImplementors(Type abstractType) { final result = <Type>[]; for (final type in scanable.annotatedTypes) { final reflector = scanable.reflectType(type); if (reflector != null && reflector.isSubtypeOf(scanable.reflectType(abstractType)!)) { // 排除抽象类本身 if (type != abstractType) { result.add(type); } } } return result; } // 使用示例 void main() { final implementors = findImplementors(MyAbstractClass); print(implementors); // 输出 [ConcreteClassA, ConcreteClassB] }@scanable注解的类不会被扫描到,要确保所有目标类都加上注解。
2. 手动注册实现类(适合小型项目)
如果不想引入反射包,直接手动维护一个实现类列表最省事:
abstract class MyAbstractClass {} class ConcreteClassA extends MyAbstractClass {} class ConcreteClassB extends MyAbstractClass {} // 手动把所有实现类加到列表里 final List<Type> myAbstractImplementors = [ ConcreteClassA, ConcreteClassB, ];
优点是简单、性能好;缺点是新增实现类时必须手动更新列表,容易漏加。
3. 代码生成自动维护注册列表
用source_gen包可以自动生成实现类列表,不用手动维护:
- 给
pubspec.yaml添加依赖:dependencies: source_gen: ^1.4.0 dev_dependencies: build_runner: ^2.4.6 - 自定义一个代码生成器,遍历项目中所有类,判断是否是目标抽象类的子类,自动生成包含所有实现类的列表代码。
- 运行
dart run build_runner build生成代码,之后直接使用生成好的列表即可。
总结
- 大型项目、实现类较多:优先选
reflectable或代码生成方案,减少手动维护成本 - 小型项目、实现类少:手动注册最省心
内容的提问来源于stack exchange,提问作者Ebrahim Mansur
相关产品推荐
相关产品推荐

