dispatch method
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;
}