DartLang中带有可反射lib的注释的simpleName

时间:2015-12-21 23:01:06

标签: dart dart-mirrors

这真的是在Dart中获取注释simpleName的唯一方法吗?

// Annotate with this class to enable reflection.
class Reflector extends Reflectable {
    const Reflector()
        : super(
            invokingCapability,metadataCapability
        );
}

const reflector = const Reflector();

// Reflector for annotation 
class MetaReflector extends Reflectable {
    const MetaReflector()
        : super(metadataCapability);
}
const metareflector = const MetaReflector();

@metareflector
class MyAnnotation {
    final String name;
    const MyAnnotation(this.name);
}

@reflector // This annotation enables reflection on A.
class A {
    final int a;
    A(this.a);

    int valueFunction() => a;
    int get value => a;

    @MyAnnotation("James Bond")
    String nameFunction() => "Mike";
}

最后一行返回SimpleName - 看起来有点复杂?

    test('> Annotation', () {
        final A a = new A(10);
        final InstanceMirror im = reflector.reflect(a);
        final ClassMirror cm = im.type;

        Map<String, MethodMirror> instanceMembers = cm.instanceMembers;
        expect(instanceMembers.keys.contains("valueFunction"),isTrue);
        expect(instanceMembers.keys.contains("value"),isTrue);
        expect(instanceMembers.keys.contains("nameFunction"),isTrue);

        final MethodMirror mm = instanceMembers["nameFunction"];
        expect(mm.isRegularMethod,isTrue);

        expect(mm.metadata.length,1);

        final x = mm.metadata.first;
        expect(x,new isInstanceOf<MyAnnotation>());
        expect((x as MyAnnotation).name,"James Bond");

        final InstanceMirror imAnnotation = metareflector.reflect(x);
        final ClassMirror cmAnnotation = imAnnotation.type;

        expect(cmAnnotation.simpleName,"MyAnnotation");
    }); // end of 'Annotation' test

1 个答案:

答案 0 :(得分:3)

在您测试expect(x,new isInstanceOf<MyAnnotation>());时,您基本上使计算结果变得微不足道:静态地知道MyAnnotation实例的类的名称是"MyAnnotation"

但是,如果您的实际使用上下文没有静态地提交注释类型,那么您将需要一种更动态的方法。获取元数据对象的类镜像(就像你一样)是一种可行的通用方法,你还需要像metaReflector这样的东西来获得查找该类镜像的支持。顺便说一下,我不明白为什么你需要metadataCapability metaReflector,但我希望它需要一个typeCapability

请注意,最新版本的reflectable需要declarationsCapability才能使用instanceMembersstaticMembers(如果没有此功能,则支持它们是异常的。)

如果您可以使事情更加静态,那么您可以选择一些中间解决方案:您可以将元数据组织到子类型层次结构中,这样您需要处理的元数据类型的每个实例都将具有{{1方法,或者您可以创建一个nameOfClass来将您要处理的每种类型的元数据转换为其名称,或者您甚至可以(原谅我;-)使用Map<Type, String>来显示名称类的任何对象都不会覆盖toString()的{​​{1}}。

最后,我建议您考虑直接使用toString()值,如果您想要在某种动态的情况下处理元数据&#34;方式:您可以查看Object并根据与Type的比较做出决定,同时您可以根据与字符串x.runtimeType的比较做出决定,只有在你想做文字之类的东西,比如&#34;任何名字与这个正则表达式匹配的类都会在这里做&#34;通过字符串获得任何东西。

(应该说MyAnnotation有点昂贵,因为它会导致在运行时保留额外的数据,特别是使用dart2js,但是当你使用reflectable时已经需要这些数据了。