addController method Null safety

  1. @override
void addController(
  1. Object controller
)
override

Add controller into _controllers and handles the methods annotated with Bind children to Controller.path and Bind.path.

In order to add the controller the class must be annotated with Controller

Just the methods that are static and are annotated with any Bind annotation will be handled.

If the Bind annotation in the method is Get the method will also be called for Head requests matching Bind.path. This is because handling Get requests without handling Head is always wrong. To explicitly implement a Head handler the method must be created before the Get handler.

throws ArgumentError if controller is not annotated with Controller

Implementation

@override
void addController(final Object controller) {
  final clazzDeclaration = reflectClass(controller.runtimeType);
  final controllerMirror = reflectClass(Controller);
  final controllerAnnotationMirror = clazzDeclaration.metadata
      .firstWhereOrNull((d) => d.type == controllerMirror);

  if (controllerAnnotationMirror == null) {
    throw ArgumentError.value(controller, 'controller',
        "doesn't contain @${controllerMirror.reflectedType}");
  }

  final ctlReflectee = controllerAnnotationMirror.reflectee as Controller;
  final methods = clazzDeclaration.declarations.values
      .where((value) => value is MethodMirror && value.isRegularMethod)
      .map((method) => method as MethodMirror);
  for (final method in methods) {
    for (final metadata in method.metadata) {
      if (metadata.type.isSubtypeOf(reflectClass(Bind))) {
        final bind = metadata.reflectee as Bind;
        final path = '${ctlReflectee.path}${bind.path}';
        final handler = RouterHandler(clazzDeclaration, method);
        _router.add(
          bind.toString(),
          path,
          handler,
        );
      }
    }
  }
  _controllers.add(controller);
}