Skip to content

Commit

Permalink
Feature : Change Newtonsoft.Json to System.Text.Json (#3562)
Browse files Browse the repository at this point in the history
<!-- Please be sure to read the
[Contribute](https://github.com/reactiveui/reactiveui#contribute)
section of the README -->

**What kind of change does this PR introduce?**
<!-- Bug fix, feature, docs update, ... -->

Feature #3190 

**What is the current behaviour?**
<!-- You can also link to an open issue here. -->

No support for System.Text.Json

**What is the new behaviour?**
<!-- If this is a feature change -->

System.Text.Json support for Serialization added

https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/migrate-from-newtonsoft?pivots=dotnet-7-0

**What might this PR break?**

If other Serializers are used verification of correct serialisation
should be confirmed

**Please check if the PR fulfills these requirements**
- [x] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)

**Other information**:
  • Loading branch information
ChrisPulman authored Nov 18, 2023
1 parent 8f11df4 commit c643a4a
Show file tree
Hide file tree
Showing 53 changed files with 225 additions and 120 deletions.
4 changes: 3 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ dotnet_diagnostic.SA1006.severity = error
dotnet_diagnostic.SA1007.severity = error
dotnet_diagnostic.SA1008.severity = error
dotnet_diagnostic.SA1009.severity = error
dotnet_diagnostic.SA1010.severity = error
dotnet_diagnostic.SA1010.severity = suggestion
dotnet_diagnostic.SA1011.severity = error
dotnet_diagnostic.SA1012.severity = error
dotnet_diagnostic.SA1013.severity = error
Expand Down Expand Up @@ -525,3 +525,5 @@ indent_size = 2
end_of_line = lf
[*.{cmd, bat}]
end_of_line = crlf

vsspell_dictionary_languages = en-US
6 changes: 5 additions & 1 deletion src/Directory.build.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
<DefaultPackageDescription>A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. Supports Xamarin.iOS, Xamarin.Android, Xamarin.Mac, Xamarin Forms, Xamarin.TVOS, Tizen, WPF, Windows Forms, Universal Windows Platform (UWP) and the Uno Platform.</DefaultPackageDescription>
<PackageDescription>$(DefaultPackageDescription)</PackageDescription>
<Owners>xanaisbettsx;ghuntley</Owners>
<PackageTags>mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen;unoplatform</PackageTags>
<PackageTags>mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net462;winui;maui;tizen;unoplatform</PackageTags>
<PackageReleaseNotes>https://github.com/reactiveui/ReactiveUI/releases</PackageReleaseNotes>
<RepositoryUrl>https://github.com/reactiveui/reactiveui</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<NoWarn>$(NoWarn);VSSpell001</NoWarn>

<!-- Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) -->
<PublishRepositoryUrl>true</PublishRepositoryUrl>
Expand All @@ -33,6 +34,9 @@
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
<PropertyGroup Condition="$(IsTestProject) != 'true'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<!-- MonoAndroid doesn't seem to want to allow debugging for maintainers -->
<PropertyGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid')) ">
Expand Down
2 changes: 1 addition & 1 deletion src/ReactiveUI.AndroidSupport/ReactivePagerAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public override void DestroyItem(ViewGroup container, int position, Object item)
throw new ArgumentNullException(nameof(item));
}

if (!(item is View view))
if (item is not View view)
{
throw new ArgumentException("Item must be of type View", nameof(item));
}
Expand Down
4 changes: 2 additions & 2 deletions src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int positi
throw new ArgumentNullException(nameof(holder));
}

if (!(holder is IViewFor viewForHolder))
if (holder is not IViewFor viewForHolder)
{
throw new ArgumentException("Holder must be derived from IViewFor", nameof(holder));
}
Expand Down Expand Up @@ -133,4 +133,4 @@ protected ReactiveRecyclerViewAdapter(TCollection backingList)
: base(backingList.ToObservableChangeSet<TCollection, TViewModel>())
{
}
}
}
10 changes: 5 additions & 5 deletions src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewViewHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System.Reflection;
using System.Runtime.Serialization;

using System.Text.Json.Serialization;
using Android.Support.V7.Widget;
using Android.Views;

Expand All @@ -23,6 +23,7 @@ public class ReactiveRecyclerViewViewHolder<TViewModel> : RecyclerView.ViewHolde
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401: Field should be private", Justification = "Legacy reasons")]
[IgnoreDataMember]
[JsonIgnore]
protected Lazy<PropertyInfo[]> AllPublicProperties = null!;

private readonly Subject<Unit> _activated = new();
Expand Down Expand Up @@ -92,30 +93,26 @@ protected ReactiveRecyclerViewViewHolder(View view)

/// <summary>
/// Gets an observable that signals that this ViewHolder has been selected.
///
/// The <see cref="int"/> is the position of this ViewHolder in the <see cref="RecyclerView"/>
/// and corresponds to the <see cref="RecyclerView.ViewHolder.AdapterPosition"/> property.
/// </summary>
public IObservable<int> Selected { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been selected.
///
/// The <see cref="IObservable{TViewModel}"/> is the ViewModel of this ViewHolder in the <see cref="RecyclerView"/>.
/// </summary>
public IObservable<TViewModel?> SelectedWithViewModel { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been long-clicked.
///
/// The <see cref="int"/> is the position of this ViewHolder in the <see cref="RecyclerView"/>
/// and corresponds to the <see cref="RecyclerView.ViewHolder.AdapterPosition"/> property.
/// </summary>
public IObservable<int> LongClicked { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been long-clicked.
///
/// The <see cref="IObservable{TViewModel}"/> is the ViewModel of this ViewHolder in the <see cref="RecyclerView"/>.
/// </summary>
public IObservable<TViewModel?> LongClickedWithViewModel { get; }
Expand All @@ -142,6 +139,7 @@ public TViewModel? ViewModel
/// Gets an observable which signals when exceptions are thrown.
/// </summary>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<Exception> ThrownExceptions => this.GetThrownExceptionsObservable();

/// <inheritdoc/>
Expand All @@ -153,10 +151,12 @@ public TViewModel? ViewModel

/// <inheritdoc/>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<IReactivePropertyChangedEventArgs<ReactiveRecyclerViewViewHolder<TViewModel>>> Changing => this.GetChangingObservable();

/// <inheritdoc/>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<IReactivePropertyChangedEventArgs<ReactiveRecyclerViewViewHolder<TViewModel>>> Changed => this.GetChangedObservable();

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion src/ReactiveUI.AndroidX/ReactivePagerAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public override void DestroyItem(ViewGroup container, int position, Object item)
throw new ArgumentNullException(nameof(item));
}

if (!(item is View view))
if (item is not View view)
{
throw new ArgumentException("Item must be of type View", nameof(item));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ReactiveUI.AndroidX/ReactiveRecyclerViewAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int positi
throw new ArgumentNullException(nameof(holder));
}

if (!(holder is IViewFor viewForHolder))
if (holder is not IViewFor viewForHolder)
{
throw new ArgumentException("Holder must be derived from IViewFor", nameof(holder));
}
Expand Down
10 changes: 5 additions & 5 deletions src/ReactiveUI.AndroidX/ReactiveRecyclerViewViewHolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

using System.Reflection;
using System.Runtime.Serialization;

using System.Text.Json.Serialization;
using Android.Views;

using AndroidX.RecyclerView.Widget;
Expand All @@ -26,6 +26,7 @@ public class ReactiveRecyclerViewViewHolder<TViewModel> : RecyclerView.ViewHolde
[SuppressMessage("Design", "CA1051: Do not declare visible instance fields", Justification = "Legacy reasons")]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1306: Field should start with a lower case letter", Justification = "Legacy reasons")]
[IgnoreDataMember]
[JsonIgnore]
protected Lazy<PropertyInfo[]>? AllPublicProperties;

private readonly Subject<Unit> _activated = new();
Expand Down Expand Up @@ -96,30 +97,26 @@ protected ReactiveRecyclerViewViewHolder(View view)

/// <summary>
/// Gets an observable that signals that this ViewHolder has been selected.
///
/// The <see cref="int"/> is the position of this ViewHolder in the <see cref="RecyclerView"/>
/// and corresponds to the <see cref="RecyclerView.ViewHolder.AdapterPosition"/> property.
/// </summary>
public IObservable<int> Selected { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been selected.
///
/// The <see cref="IObservable{TViewModel}"/> is the ViewModel of this ViewHolder in the <see cref="RecyclerView"/>.
/// </summary>
public IObservable<TViewModel?> SelectedWithViewModel { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been long-clicked.
///
/// The <see cref="int"/> is the position of this ViewHolder in the <see cref="RecyclerView"/>
/// and corresponds to the <see cref="RecyclerView.ViewHolder.AdapterPosition"/> property.
/// </summary>
public IObservable<int> LongClicked { get; }

/// <summary>
/// Gets an observable that signals that this ViewHolder has been long-clicked.
///
/// The <see cref="IObservable{TViewModel}"/> is the ViewModel of this ViewHolder in the <see cref="RecyclerView"/>.
/// </summary>
public IObservable<TViewModel?> LongClickedWithViewModel { get; }
Expand All @@ -146,6 +143,7 @@ public TViewModel? ViewModel
/// Gets an observable which signals when exceptions are thrown.
/// </summary>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<Exception> ThrownExceptions => this.GetThrownExceptionsObservable();

/// <inheritdoc/>
Expand All @@ -157,10 +155,12 @@ public TViewModel? ViewModel

/// <inheritdoc/>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<IReactivePropertyChangedEventArgs<ReactiveRecyclerViewViewHolder<TViewModel>>> Changing => this.GetChangingObservable();

/// <inheritdoc/>
[IgnoreDataMember]
[JsonIgnore]
public IObservable<IReactivePropertyChangedEventArgs<ReactiveRecyclerViewViewHolder<TViewModel>>> Changed => this.GetChangedObservable();

/// <inheritdoc/>
Expand Down
2 changes: 1 addition & 1 deletion src/ReactiveUI.Blend/Platforms/net4/ObservableTrigger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public IObservable<object> Observable
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
protected static void OnObservableChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (!(sender is ObservableTrigger triggerItem))
if (sender is not ObservableTrigger triggerItem)
{
throw new ArgumentException("Sender must be of type " + nameof(ObservableTrigger), nameof(sender));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ReactiveUI.Maui/ViewModelViewHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public ViewModelViewHost()
throw new Exception($"Couldn't find view for '{x.ViewModel}'.");
}

if (!(view is View castView))
if (view is not View castView)
{
throw new Exception($"View '{view.GetType().FullName}' is not a subclass of '{typeof(View).FullName}'.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,10 +716,13 @@ namespace ReactiveUI
{
public ReactiveObject() { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changed { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changing { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<System.Exception> ThrownExceptions { get; }
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
public event System.ComponentModel.PropertyChangingEventHandler? PropertyChanging;
Expand All @@ -742,10 +745,13 @@ namespace ReactiveUI
{
public ReactiveRecord() { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changed { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changing { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<System.Exception> ThrownExceptions { get; }
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
public event System.ComponentModel.PropertyChangingEventHandler? PropertyChanging;
Expand Down Expand Up @@ -800,17 +806,23 @@ namespace ReactiveUI
{
public RoutingState(System.Reactive.Concurrency.IScheduler? scheduler = null) { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IRoutableViewModel> CurrentViewModel { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<ReactiveUI.IRoutableViewModel, ReactiveUI.IRoutableViewModel> Navigate { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<ReactiveUI.IRoutableViewModel, ReactiveUI.IRoutableViewModel> NavigateAndReset { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<System.Reactive.Unit, ReactiveUI.IRoutableViewModel> NavigateBack { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<DynamicData.IChangeSet<ReactiveUI.IRoutableViewModel>> NavigationChanged { get; set; }
[System.Runtime.Serialization.DataMember]
public System.Collections.ObjectModel.ObservableCollection<ReactiveUI.IRoutableViewModel> NavigationStack { get; }
[System.Text.Json.Serialization.JsonRequired]
public System.Collections.ObjectModel.ObservableCollection<ReactiveUI.IRoutableViewModel> NavigationStack { get; set; }
}
public static class RoutingStateMixins
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -716,10 +716,13 @@ namespace ReactiveUI
{
public ReactiveObject() { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changed { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changing { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<System.Exception> ThrownExceptions { get; }
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
public event System.ComponentModel.PropertyChangingEventHandler? PropertyChanging;
Expand All @@ -742,10 +745,13 @@ namespace ReactiveUI
{
public ReactiveRecord() { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changed { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IReactivePropertyChangedEventArgs<ReactiveUI.IReactiveObject>> Changing { get; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<System.Exception> ThrownExceptions { get; }
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
public event System.ComponentModel.PropertyChangingEventHandler? PropertyChanging;
Expand Down Expand Up @@ -800,17 +806,23 @@ namespace ReactiveUI
{
public RoutingState(System.Reactive.Concurrency.IScheduler? scheduler = null) { }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<ReactiveUI.IRoutableViewModel> CurrentViewModel { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<ReactiveUI.IRoutableViewModel, ReactiveUI.IRoutableViewModel> Navigate { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<ReactiveUI.IRoutableViewModel, ReactiveUI.IRoutableViewModel> NavigateAndReset { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public ReactiveUI.ReactiveCommand<System.Reactive.Unit, ReactiveUI.IRoutableViewModel> NavigateBack { get; set; }
[System.Runtime.Serialization.IgnoreDataMember]
[System.Text.Json.Serialization.JsonIgnore]
public System.IObservable<DynamicData.IChangeSet<ReactiveUI.IRoutableViewModel>> NavigationChanged { get; set; }
[System.Runtime.Serialization.DataMember]
public System.Collections.ObjectModel.ObservableCollection<ReactiveUI.IRoutableViewModel> NavigationStack { get; }
[System.Text.Json.Serialization.JsonRequired]
public System.Collections.ObjectModel.ObservableCollection<ReactiveUI.IRoutableViewModel> NavigationStack { get; set; }
}
public static class RoutingStateMixins
{
Expand Down
Loading

0 comments on commit c643a4a

Please sign in to comment.