dispatch method

  1. @override
Future dispatch(
  1. String methodName, [
  2. dynamic positionalParams,
  3. Map<String, dynamic>? namedParams
])

Invoke named method with parameters on the instance and return a Future of the result, if possible.

Catch, repackage and return (not throw or rethrow) All Errors. positionalParams should be a List or null. namedParams should be a Map of String:value or null.

Implementation

@override
Future dispatch(String methodName,
    [dynamic positionalParams, Map<String, dynamic>? namedParams]) async {
  namedParams = namedParams ?? <String, dynamic>{};
  var posParams = positionalParams ?? [];
  if (posParams is Map<String, dynamic>) {
    namedParams = positionalParams;
    posParams = [];
  }

  if (posParams is! List) {
    posParams = [posParams];
  }
  namedParams = namedParams ?? <String, dynamic>{};
  var symbolMap = <Symbol, dynamic>{};
  if (namedParams.isNotEmpty) {
    symbolMap = symbolizeKeys(namedParams);
  }

  var instanceMirror = mirror.reflect(instance);

  // error check the method and parameter counts
  var methodSchemas = instanceMirror.type.declarations;
  if (methodSchemas.containsKey(methodName)) {
    var params = methodSchemas[methodName].parameters;
    var namedCount = 0;
    var optionals = 0;
    for (var p in params) {
      if (p.isNamed) {
        namedCount += 1;
      }
      if (p.isOptional) {
        optionals += 1;
      }
    }
    var actualCount = posParams.length;
    var requiredCount = params.length - namedCount - optionals;
    if (actualCount < requiredCount) {
      return InvalidParametersException('too few params');
    }
    if (actualCount > requiredCount + optionals) {
      return InvalidParametersException('too many params');
    }
  } else {
    return MethodNotFoundException('Not found: $methodName');
  }

  var resp;
  try {
    resp = await instanceMirror.invoke(methodName, posParams, symbolMap);
  } on TypeError catch (e) {
    return InvalidParametersException('$e');
  } catch (e) {
    // passthrough for custom user-correctable errors
    if (e is RuntimeException) {
      return e;
    }
    return RuntimeException('$e');
  }
  return resp;
}