Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Router State is No Longer Saved To Disk #3322

Closed
worldbeater opened this issue Jul 23, 2022 · 3 comments 路 Fixed by #3379
Closed

[Bug]: Router State is No Longer Saved To Disk #3322

worldbeater opened this issue Jul 23, 2022 · 3 comments 路 Fixed by #3379
Labels

Comments

@worldbeater
Copy link
Contributor

worldbeater commented Jul 23, 2022

Describe the bug 馃悶

Earlier, we were able to save RoutingState.NavigationStack to disk, as the collection was annotated as a [DataMember]: https://github.com/reactiveui/ReactiveUI/blame/a43e99ae2fbcd644460f245f471f573b7d3b66ec/src/ReactiveUI/Routing/RoutingState.cs#L26-L27

But now, the observable collection is [IgnoreDataMember]d: https://github.com/reactiveui/ReactiveUI/blob/main/src/ReactiveUI/Routing/RoutingState.cs#L50-L51

Step to reproduce

  1. Clone https://github.com/reactiveui/ReactiveUI.Samples/
  2. Navigate to https://github.com/reactiveui/ReactiveUI.Samples/tree/main/avalonia/suspension/
  3. Launch ReactiveUI.Samples.Suspension.sln,
  4. Try updating ReactiveUI to the latest version,
  5. RoutingState.NavigationStack is no longer saved to disk when the app is closed.

Reproduction repository

https://github.com/reactiveui/ReactiveUI.Samples/

Expected behavior

ReactiveUI suspension feature used to be working according to this guide: https://habr.com/en/post/462307/
And according to the documentation page: https://www.reactiveui.net/docs/handbook/data-persistence/
Probably worth marking NavigationStack as DataMember again and adding back a default ctor, if this won't cause issues, and if these were removed unintentionally.

ReactiveUI Version

17.0.1+

@natekford
Copy link

natekford commented Aug 26, 2022

I encountered this issue and wrote this hack to get around it:

private sealed class NavigationStackResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var props = base.CreateProperties(type, memberSerialization);
        foreach (var prop in props)
        {
            if (prop.DeclaringType == typeof(RoutingState)
                && prop.PropertyName == nameof(RoutingState.NavigationStack))
            {
                prop.Ignored = false;
                prop.Writable = true;
                prop.ValueProvider = new NavigationStackValueProvider(prop.ValueProvider!);
            }
        }
        return props;
    }
}

private sealed class NavigationStackValueProvider : IValueProvider
{
    private readonly IValueProvider _Original;

    public NavigationStackValueProvider(IValueProvider original)
    {
        _Original = original;
    }

    public object? GetValue(object target)
        => _Original.GetValue(target);

    public void SetValue(object target, object? value)
    {
        var castedTarget = (RoutingState)target!;
        var castedValue = (IEnumerable<IRoutableViewModel>)value!;

        castedTarget.NavigationStack.Clear();
        foreach (var vm in castedValue)
        {
            castedTarget.NavigationStack.Add(vm);
        }
    }
}

@glennawatson
Copy link
Contributor

If anyone is willing, be happy to take a PR for the affected systems. I been under the pump lately and should be a easy PR for anyone to pick up.

Also thanks for the workaround @advorange

@ChrisPulman
Copy link
Member

Closing as this looks complete and no further issues have been raised

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants