Understanding Reflection and Annotations in Dart
Tags: dart, showdev, webdev, codequality
Published: 2019-07-01 06:07:36

_Originally posted at [creativebracket.com](https://creativebracket.com/understanding-reflection-and-annotations-in-dart/)_

In this video, we will explore the topic of Reflection and how that can be used to write cleaner software. Reflection allow us to examine and modify the structure and behaviour of a program at runtime. We will be working with the **dart:mirrors** library which contains helper classes and functions for achieving this. We will end by looking at a common use case with **Annotations**.

{%youtube _2yjPLVEGs4%}

## Basic example with Reflection

Create a `main.dart` file and start by importing the **dart:mirrors** library. Before we implement our reflection logic let's also define a class with a method we wish to invoke:

```dart
import 'dart:mirrors';

main() {
  // TODO: Implement Reflection logic
}

// Our example class to reflect on
class Endpoint {
  handle() => print('Request received');
}
```

To reflect on types and objects we have three methods to work with:

1. **reflect()**: Reflects on an instance of a class
2. **reflectClass()**: Reflects on a class declaration
3. **reflectType()**: Reflects on the type passed in as the argument

In our case we will use `reflect()`. Let's instantiate `Endpoint` and invoke the handle method via reflection:

```dart
main() {
  var reflectedClass = reflect(Endpoint());

  // invoke the handle() method
  reflectedclass.invoke(Symbol'handle'), []);
}
```

And then let's run this file:

```bash
$ dart /path/to/main.dart
```

Reflecting an instance provides us with an `InstanceMirror` that exposes the `invoke()` method. The members of our instance are depicted as `Symbol` types. The example above invokes the handle method by passing its `Symbol`ic name along with an array of positional arguments if any are specified.

To pass arguments across, let's modify the signature of the `handle()` method:

```dart
handle(String a) => print('Request received $a');
```
And pass this to the invocation:

```dart
reflectedClass.invoke(Symbol('handle'), ['argument 1']);
// => Request received argument 1
```
You can use the literal form of the `handle()` method:

```dart
reflectedClass.invoke(#handle, ['argument 1']);
```
You can use the `Symbol('methodName')` approach if the method name is received as a value from an operation or provided as user input. _Ideally when you **don't** know beforehand the method to invoke._

Watch the video above for the full tutorial.

→ [**Get the source code**](https://gist.github.com/graphicbeacon/9fb6c6a951168d6a31d9b2cc442bcbe2)


## Further reading

* [**dart:mirrors** library documentation](https://api.dart.dev/stable/2.4.0/dart-mirrors/dart-mirrors-library.html)
* [Dart and MongoDB Tutorial #1: Using the mongo_dart package](https://creativebracket.com/dart-and-mongodb-tutorial-1)

---

## One last thing...

I'm glad to announce that I've hit **over 7000 followers** on dev.to. Thanks a lot for all the growing interest, support and the feedback I've received!

In light of that I'm launching the [**Official Merch Store**](//bit.ly/creativebracketmerch) today. It's a great opportunity to be a part of the movement and keep the flames🔥 lit. That would drive the production of high-quality content covering topics further than "hello world" apps.

I've also hit over 800 subscribers on the YouTube channel. [**Hit that subscribe and bell notification**](https://youtube.com/CreativeBracket) if you haven't already. I plan on doing a series on code generation among other things quite soon.

Lastly, there are more tutorials on my blog at [creativebracket.com](https://creativebracket.com). Do check 'em out.

**Like, share and follow** me for more content on Dart. _Thanks._