Note: this is not the same as Passing Realm objects between ViewControllers
I am trying to find a way to pass a Realm Transaction
between two ViewModel
s. Currently, the Transaction
is opened in a detail view, so I can only access it in the detail view. I have a need to Dispose
it back in the master view, so I am thinking that I could begin the Transaction
before navigating to the detail view, like so:
var trans = realm.BeginWrite();
NavigationService.Navigate(typeof(DetailPage), trans);
However, a Realm Transaction
is not serializable, so this method does not work. I am using Template10 in a UWP application. In a Xamarin application (QuickJournal example), this can be accomplished like this:
var transaction = realm.BeginWrite();
...
var page = new JournalEntryDetailsPage(new JournalEntryDetailsViewModel(entry, transaction));
Navigation.PushAsync(page);
As far as I can tell, there isn't a way to pass arguments to a constructor using Template10's NavigationService
. I would be happy to be able to either: a) pass the Transaction
from the master view to the detail view in the constructor, or b) somehow access the detail view's Transaction
from the master view.
My current workaround is to not use a Transaction
at all, but to create an unmanaged copy of the RealmObject
in the detail view, but this doesn't seem like a great permanent solution.
You could implement a poor man's injection cache to work around the serialization limitation:
public static class Injector
{
private static readonly ConcurrentDictionary<Guid, object> _dict = new ConcurrentDictionary<Guid, object>();
public static Guid Store(object value)
{
var key = Guid.NewGuid();
_dict.TryAdd(key, value);
return key;
}
public static object Retrieve(Guid guid)
{
if (!_dict.TryRemove(guid, out var result))
{
throw new Exception("Key not found");
}
return result;
}
}
Then in your master ViewModel you could do:
var key = Injector.Store(realm.BeginWrite());
NavigationService.Navigate(typeof(DetailPage), key);
And then in your detail ViewModel, you can retrieve the transaction:
_transaction = Injector.Retrieve(key);