2013-01-09 4 views

Antwort

3

Sie müssen den Namen der Bibliothek und Klasse wissen Name, um Dinge richtig zu machen. Angenommen, Sie kennen beide, das folgende Beispiel instanziiert die TestClass und rufen Sie doStuff darauf.

library test; 

import "dart:mirrors"; 

class TestClass { 
    doStuff() => print("doStuff was called!"); 
} 

main() { 
    MirrorSystem mirrors = currentMirrorSystem(); 
    LibraryMirror lm = mirrors.libraries['test']; 
    ClassMirror cm = lm.classes['TestClass']; 
    Future tcFuture = cm.newInstance('', []); 
    tcFuture.then((InstanceMirror im) { 
    var tc = im.reflectee; 
    tc.doStuff(); 
    }); 
} 

Ein paar Anmerkungen zu dieser Lösung:

  1. Die Bibliothek test wir versuchen, aus der Klasse zu laden ist bereits in der VM importiert, die diesen Fall ein bisschen einfacher macht.
  2. der Aufruf der newInstance ermöglicht die Übergabe von Parametern an den Konstruktor. Positionsargumente werden implementiert, benannte Parameter sind jedoch noch nicht implementiert (ab Release M2).
  3. newInstance gibt Future zurück, damit es über isolates funktioniert.
+0

'newInstance' gibt keine' Zukunft' zurück, da das Instanziieren der Klasse eine asynchrone Operation erfordert, das ist nicht wahr, alles ist bereits geladen. Es gibt eine 'Zukunft' zurück, da die Mirrors-API absichtlich asynchron ist, da sie in der Zukunft isolationsübergreifend funktioniert (und die Kommunikation übergreifend immer asynchron ist). Wenn Sie den 'newInstance'-Aufruf (und andere wie 'get/setField' oder' invoke') sorgfältig untersuchen, werden Sie feststellen, dass er unter der Haube synchron arbeitet. Das könnte sich in Zukunft natürlich ändern. – Ladicek

+0

Dank Ladicek. Ich habe die Antwort aktualisiert. – Kyrra

+0

Hinweis: Dies funktioniert möglicherweise nicht, wenn es in JavaScript kompiliert wird. Der dart2js-Compiler unterstützt Spiegel noch nicht vollständig. –

4

Die Syntax hat sich geändert. Ich habe es auf diese Weise arbeiten

library test; 

import "dart:mirrors"; 

class TestClass { 
    doStuff() => print("doStuff was called!"); 
} 

main() { 
    MirrorSystem mirrors = currentMirrorSystem(); 
    LibraryMirror lm = mirrors.libraries.values.firstWhere(
     (LibraryMirror lm) => lm.qualifiedName == new Symbol('test')); 

    ClassMirror cm = lm.declarations[new Symbol('TestClass')]; 

    InstanceMirror im = cm.newInstance(new Symbol(''), []); 
    var tc = im.reflectee; 
    tc.doStuff(); 
} 

Wenn es mehr Bibliotheken namens ‚Test‘ sind dies allerdings fehl.

+0

In der Tat, 'Klassen' Getter wurde in' Deklarationen' geändert. – snitko