I use to pass the context when needed, as dlohani suggests in the comment at the question, but I found myself in the same situation and applied a solution inspired by the communication pattern used between isolates: messages exchange.
The Provider class need to have a ReceiverPort
field which listens to request messages. Ones the message reaches this listener you're inside the Provider, so you can retrieve data and send them back, again in the ReceiverPort's fashion, that is using the sendPort of the ReceiverPort registered in the requesting class.
In code below I suppose messages are Map
s to clarify the type of data exchanged:
class SomeProvider with ChangeNotifier {
var _innerData = yourData;
var _providerReceiverPort = ReceiverPort();
SomeProvider() {
// The registration is necessary to "publish" the receiver port
IsolateNameServer.registerPortWithName(
_providerReceiverPort, "SomeProviderPort");
_providerReceiverPort.listen(
(message) {
// I retrieve the port to send the response to
var port = message["sendPort"];
// The answer follows the rules of messaging: maps and lists are ok
port.send({"data": _innerData.getSomething()});
}
);
}
}
class SomeClient {
var _clientReceiverPort = ReceiverPort();
someFunction(){
// First step: prepare the receiver to obtain data
_clientReceiverPort.listen(
(message) {
// Data are stored in the map containing a "data" key
var response = message["data"];
...
}
);
// Now I can retrieve the provider port by using the same name it uses to publish it
var providerPort = IsolateNameServer.lookupPortByName("SomeProviderPort");
// The message must include the sendPort to permit the provider to address the response
providerPort.send({"sendPort": _clientReceiverPort.sendPort});
}
}
The drawback of this solution is that the Provider doesn't work as a provider for the SomeClient class. You can obviously notify if any change in the listener is important for the subscribers: for example, I use this pattern to update data in the provider from a background isolate.
As I said, this is a workaround, any suggestion to improve is welcome.