What is Flutter Reflection with Reflectable in Dart?

What is Flutter Reflection with Reflectable in Dart?

Flutter: Overview

Free and open-source, Flutter is a framework for creating native-looking applications for both iOS and Android. When it comes to developing mobile apps that are both speedy and functional, Flutter is an excellent tool for any Flutter agency to have on their side!

Flutter aids in the development of cross-platform mobile apps that are quick, well-designed, and universally compatible. Let’s take a look at Google’s newest UI framework, Flutter, and see how it works with reflection.

Metadata for Dart

Dart Metadata is used to provide more information about the Dart program. It is often preceded by the @ symbol and followed by a reference to a compile-time variable or a call to the variable constructor.

Annotating Metadata

We can specify our own metadata annotations in Dart. Here is an example of how to define a @student annotation that accepts two parameters –

library student;
Class Student {
final String studentName;
final String rollno;
const Student(this.studentName, this.rollno);
}

Likewise, in the following example, we will utilize the @student annotation.

import 'student.dart' ;
@Student('studentName', 'rollno')
void greetHii() {
print("Hii Welcome to flutter agency");
}

In Dart, metadata is often defined immediately before a library reference, class, class parameter, typedef, field, factory, method, constructor, variable, or a variable expression, as well as immediately before an import or export command. In runtime, we may access the metadata via reflection.

Interpreting Dart’s Reflection and Annotation

Reflection enables us to inspect and adjust a program’s structure and behavior at runtime. We will do this by utilizing the dart:mirrors library, which offers assistance classes and functions. We’ll conclude by discussing a frequent use case for Annotations.

Example with Reflection

Begin by creating a main.dart file and importing the dart:mirrors dependency. Before we begin implementing our reflection logic, let us construct a class with the following method:

import 'dart:mirrors';
main() {
// TODO: Implement Reflection logic
}
// Our example class to reflect on
class Endpoint {
handle() => print('Request received');
}

Three ways are available for reflecting on types and objects:

reflect(): Tends to reflect on a class instance.
reflectClass(): Reflects a class definition using the reflectClass() method.
reflectType(): Returns the type specified as an input.

In our example, we’ll utilize reflect (). Let’s use reflection to call the handle function on an Endpoint we’ve just created.

main() {
var reflectedClass = reflect(Endpoint());
// Invoke the handle() method
reflectedClass.

After that, let us execute the following file:

$ dart /path/to/main.dart

Reflecting on an instance gives us an InstanceMirror that reveals the invoke() function, which we can use to call the invoke() method. Symbol types are used to represent the components of our instance.

The handle method is invoked in the example above by giving its Symbolic name, as well as an array of positional arguments, if any are supplied, to the method’s callback function.

To facilitate the passing of parameters, let us alter the signature of the handle() function as follows:

handle(String a) => print('Request received $a');

And now for the invocation:

reflectedClass.invoke(Symbol('handle'), ['argument 1']);
// => Request received argument 1

You may also use the handle() symbol in its literal form, which is as follows:

reflectedClass.invoke(#handle, ['argument 1']);
reflectedClass.invoke(#handle, ['argument 2']);

This strategy can be used when the method name is received as a value from an operation or when the user gives the method name. When you aren’t sure which strategy to use, this is the best option to choose.

The use of Annotations for Reflection

import 'dart:mirrors';
import 'lib/some_class.dart';
import 'lib/some_annotation.dart';
void main() {
printAnnotationValue(String);
printAnnotationValue(SomeClass);
}
void printAnnotationValue(final Type clazz) {
final DeclarationMirror clazzDeclaration = reflectClass(clazz);
final ClassMirror someAnnotationMirror = reflectClass(SomeAnnotation);
final annotationInstsanceMirror = clazzDeclaration.metadata.firstWhere((d) => d.type == someAnnotationMirror, orElse: () => null);
if (annotationInstsanceMirror == null) {
print('Annotation is not on this class');
return;
}
final someAnnotationInstance = (annotationInstsanceMirror.reflectee as SomeAnnotation);
print("${someAnnotationInstance.someField}");
}

Let’s take a look at some of the lines that need attention:

Line 1: The dart mirrors are imported in the first line. There are many reflection abstractions in the dart mirrors library. All three of these types of mirrors are available in the Mirror class: one for Instances and one for Declarations, and the third one for Classes.

Line 5: This is our main program, and we will compare the results of running printAnnotationValue on two classes: one that contains the SomeAnnotation and one that does not. As you can see, String does not have this annotation at all.

Line 11: We obtain a DeclarationMirror for the given type by utilizing the reflectClass helper (both are included in the mirrors lib) (either String or SomeClass in this app)

Line 12: we obtain the mirror in order to annotate SomeAnnotation

Line 13: we traverse over the metadata for the specified type, looking for instances of the type SomeAnnotation.

Line 15: If no such instance mirror is discovered, we print that the specified type lacks the annotation.

Line 20: If the annotation’s instance reflection is discovered, we obtain the actual instance (not the instance mirror) and simply display the value.

Conclusion

In this post, we’ve given you all the details you need about Flutter Reflection using Reflectable. We hope you find this information helpful, and if you have any suggestions or feedback, please feel free to contact us.

FlutterAgency.com is a portal platform for Flutter advanced technologies and Flutter professionals. Resources like Flutter Widget Guide, Flutter Projects, Code libs, and more may be found in our portal.

Abhishek Dhanani

Written by Abhishek Dhanani

Abhishek Dhanani, a skilled software developer with 3+ years of experience, masters Dart, JavaScript, TypeScript, and frameworks like Flutter and NodeJS. Proficient in MySQL, Firebase, and cloud platforms AWS and GCP, he delivers innovative digital solutions.

Leave a comment

Your email address will not be published. Required fields are marked *


ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields

✓ Valid number ✕ Invalid number
our share of the limelight

as seen on