Skip to content

Commit 84be0b1

Browse files
authored
Remove BinaryFormatter, Start Adding AOT Markup (#3943)
<!-- 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, ... --> update **What is the current behavior?** <!-- You can also link to an open issue here. --> BinaryFormatter is used for suspension **What is the new behavior?** <!-- If this is a feature change --> Remove BinaryFormatter Start adding AOT Markup **What might this PR break?** Suspension will fail to Deserialize **** BREAKING CHANGE **** **Please check if the PR fulfills these requirements** - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Docs have been added / updated (for bug fixes / features) **Other information**:
1 parent 3c84778 commit 84be0b1

16 files changed

+121
-23
lines changed

src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet8_0.verified.txt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,25 @@ namespace ReactiveUI
117117
public class CreatesCommandBindingViaCommandParameter : ReactiveUI.ICreatesCommandBinding
118118
{
119119
public CreatesCommandBindingViaCommandParameter() { }
120+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
121+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
120122
public System.IDisposable? BindCommandToObject(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter) { }
121123
public System.IDisposable? BindCommandToObject<TEventArgs>(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter, string eventName) { }
124+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
125+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
122126
public int GetAffinityForObject(System.Type type, bool hasEventTarget) { }
123127
}
124128
public class CreatesCommandBindingViaEvent : ReactiveUI.ICreatesCommandBinding
125129
{
126130
public CreatesCommandBindingViaEvent() { }
131+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
132+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
127133
public System.IDisposable? BindCommandToObject(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter) { }
134+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
135+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
128136
public System.IDisposable? BindCommandToObject<TEventArgs>(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter, string eventName) { }
137+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
138+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
129139
public int GetAffinityForObject(System.Type type, bool hasEventTarget) { }
130140
}
131141
public class DecimalToStringTypeConverter : ReactiveUI.IBindingTypeConverter, Splat.IEnableLogger
@@ -137,6 +147,8 @@ namespace ReactiveUI
137147
public sealed class DefaultViewLocator : ReactiveUI.IViewLocator, Splat.IEnableLogger
138148
{
139149
public System.Func<string, string> ViewModelToViewFunc { get; set; }
150+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The method is used to resolve views for view models.")]
151+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
140152
public ReactiveUI.IViewFor? ResolveView<T>(T? viewModel, string? contract = null) { }
141153
}
142154
public static class DependencyResolverMixins
@@ -369,7 +381,7 @@ namespace ReactiveUI
369381
public interface ISuspensionDriver
370382
{
371383
System.IObservable<System.Reactive.Unit> InvalidateState();
372-
System.IObservable<object> LoadState();
384+
System.IObservable<object?> LoadState();
373385
System.IObservable<System.Reactive.Unit> SaveState(object state);
374386
}
375387
public interface ISuspensionHost : ReactiveUI.IReactiveObject, Splat.IEnableLogger, System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging
@@ -813,6 +825,8 @@ namespace ReactiveUI
813825
public static class Reflection
814826
{
815827
public static string ExpressionToPropertyNames(System.Linq.Expressions.Expression? expression) { }
828+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeMethods()")]
829+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeMethods()")]
816830
public static System.Type GetEventArgsTypeForEvent(System.Type type, string? eventName) { }
817831
public static System.Func<object?, object?[]?, object?>? GetValueFetcherForProperty(System.Reflection.MemberInfo? member) { }
818832
public static System.Func<object?, object?[]?, object?> GetValueFetcherOrThrow(System.Reflection.MemberInfo? member) { }
@@ -821,6 +835,8 @@ namespace ReactiveUI
821835
public static bool IsStatic(this System.Reflection.PropertyInfo item) { }
822836
public static System.Type? ReallyFindType(string? type, bool throwOnFailure) { }
823837
public static System.Linq.Expressions.Expression Rewrite(System.Linq.Expressions.Expression? expression) { }
838+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetTypeInfo()")]
839+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetTypeInfo()")]
824840
public static void ThrowIfMethodsNotOverloaded(string callingTypeName, object targetObject, params string[] methodsToCheck) { }
825841
public static bool TryGetAllValuesForPropertyChain(out ReactiveUI.IObservedChange<object, object?>[] changeValues, object? current, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression> expressionChain) { }
826842
public static bool TryGetValueForPropertyChain<TValue>(out TValue changeValue, object? current, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression> expressionChain) { }

src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.DotNet9_0.verified.txt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,25 @@ namespace ReactiveUI
117117
public class CreatesCommandBindingViaCommandParameter : ReactiveUI.ICreatesCommandBinding
118118
{
119119
public CreatesCommandBindingViaCommandParameter() { }
120+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
121+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
120122
public System.IDisposable? BindCommandToObject(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter) { }
121123
public System.IDisposable? BindCommandToObject<TEventArgs>(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter, string eventName) { }
124+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
125+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
122126
public int GetAffinityForObject(System.Type type, bool hasEventTarget) { }
123127
}
124128
public class CreatesCommandBindingViaEvent : ReactiveUI.ICreatesCommandBinding
125129
{
126130
public CreatesCommandBindingViaEvent() { }
131+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
132+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
127133
public System.IDisposable? BindCommandToObject(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter) { }
134+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
135+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
128136
public System.IDisposable? BindCommandToObject<TEventArgs>(System.Windows.Input.ICommand? command, object? target, System.IObservable<object?> commandParameter, string eventName) { }
137+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
138+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
129139
public int GetAffinityForObject(System.Type type, bool hasEventTarget) { }
130140
}
131141
public class DecimalToStringTypeConverter : ReactiveUI.IBindingTypeConverter, Splat.IEnableLogger
@@ -137,6 +147,8 @@ namespace ReactiveUI
137147
public sealed class DefaultViewLocator : ReactiveUI.IViewLocator, Splat.IEnableLogger
138148
{
139149
public System.Func<string, string> ViewModelToViewFunc { get; set; }
150+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The method is used to resolve views for view models.")]
151+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
140152
public ReactiveUI.IViewFor? ResolveView<T>(T? viewModel, string? contract = null) { }
141153
}
142154
public static class DependencyResolverMixins
@@ -369,7 +381,7 @@ namespace ReactiveUI
369381
public interface ISuspensionDriver
370382
{
371383
System.IObservable<System.Reactive.Unit> InvalidateState();
372-
System.IObservable<object> LoadState();
384+
System.IObservable<object?> LoadState();
373385
System.IObservable<System.Reactive.Unit> SaveState(object state);
374386
}
375387
public interface ISuspensionHost : ReactiveUI.IReactiveObject, Splat.IEnableLogger, System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging
@@ -813,6 +825,8 @@ namespace ReactiveUI
813825
public static class Reflection
814826
{
815827
public static string ExpressionToPropertyNames(System.Linq.Expressions.Expression? expression) { }
828+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetRuntimeMethods()")]
829+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetRuntimeMethods()")]
816830
public static System.Type GetEventArgsTypeForEvent(System.Type type, string? eventName) { }
817831
public static System.Func<object?, object?[]?, object?>? GetValueFetcherForProperty(System.Reflection.MemberInfo? member) { }
818832
public static System.Func<object?, object?[]?, object?> GetValueFetcherOrThrow(System.Reflection.MemberInfo? member) { }
@@ -821,6 +835,8 @@ namespace ReactiveUI
821835
public static bool IsStatic(this System.Reflection.PropertyInfo item) { }
822836
public static System.Type? ReallyFindType(string? type, bool throwOnFailure) { }
823837
public static System.Linq.Expressions.Expression Rewrite(System.Linq.Expressions.Expression? expression) { }
838+
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Calls GetTypeInfo()")]
839+
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Calls GetTypeInfo()")]
824840
public static void ThrowIfMethodsNotOverloaded(string callingTypeName, object targetObject, params string[] methodsToCheck) { }
825841
public static bool TryGetAllValuesForPropertyChain(out ReactiveUI.IObservedChange<object, object?>[] changeValues, object? current, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression> expressionChain) { }
826842
public static bool TryGetValueForPropertyChain<TValue>(out TValue changeValue, object? current, System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression> expressionChain) { }

src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.Net4_7.verified.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ namespace ReactiveUI
367367
public interface ISuspensionDriver
368368
{
369369
System.IObservable<System.Reactive.Unit> InvalidateState();
370-
System.IObservable<object> LoadState();
370+
System.IObservable<object?> LoadState();
371371
System.IObservable<System.Reactive.Unit> SaveState(object state);
372372
}
373373
public interface ISuspensionHost : ReactiveUI.IReactiveObject, Splat.IEnableLogger, System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.INotifyPropertyChanging

src/ReactiveUI/Bindings/Command/CreatesCommandBinding.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public static IDisposable BindCommandToObject(ICommand? command, object? target,
4040
return ret;
4141
}
4242

43+
#if NET6_0_OR_GREATER
44+
[RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
45+
[RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
46+
#endif
4347
public static IDisposable BindCommandToObject(ICommand? command, object? target, IObservable<object?> commandParameter, string? eventName)
4448
{
4549
var type = target!.GetType();

src/ReactiveUI/Bindings/Command/CreatesCommandBindingViaCommandParameter.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ namespace ReactiveUI;
1414
public class CreatesCommandBindingViaCommandParameter : ICreatesCommandBinding
1515
{
1616
/// <inheritdoc/>
17+
#if NET6_0_OR_GREATER
18+
[RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
19+
[RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
20+
#endif
1721
public int GetAffinityForObject(Type type, bool hasEventTarget)
1822
{
1923
if (hasEventTarget)
@@ -35,6 +39,10 @@ public int GetAffinityForObject(Type type, bool hasEventTarget)
3539
}
3640

3741
/// <inheritdoc/>
42+
#if NET6_0_OR_GREATER
43+
[RequiresUnreferencedCode("Calls GetRuntimeProperty(string name)")]
44+
[RequiresDynamicCode("Calls GetRuntimeProperty(string name)")]
45+
#endif
3846
public IDisposable? BindCommandToObject(ICommand? command, object? target, IObservable<object?> commandParameter)
3947
{
4048
target.ArgumentNullExceptionThrowIfNull(nameof(target));

src/ReactiveUI/Bindings/Command/CreatesCommandBindingViaEvent.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public class CreatesCommandBindingViaEvent : ICreatesCommandBinding
3030
];
3131

3232
/// <inheritdoc/>
33+
#if NET6_0_OR_GREATER
34+
[RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
35+
[RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
36+
#endif
3337
public int GetAffinityForObject(Type type, bool hasEventTarget)
3438
{
3539
if (hasEventTarget)
@@ -45,6 +49,10 @@ public int GetAffinityForObject(Type type, bool hasEventTarget)
4549
}
4650

4751
/// <inheritdoc/>
52+
#if NET6_0_OR_GREATER
53+
[RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
54+
[RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
55+
#endif
4856
public IDisposable? BindCommandToObject(ICommand? command, object? target, IObservable<object?> commandParameter)
4957
{
5058
target.ArgumentNullExceptionThrowIfNull(nameof(target));
@@ -61,6 +69,10 @@ public int GetAffinityForObject(Type type, bool hasEventTarget)
6169
}
6270

6371
/// <inheritdoc/>
72+
#if NET6_0_OR_GREATER
73+
[RequiresUnreferencedCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
74+
[RequiresDynamicCode("Calls System.Reflection.MethodInfo.MakeGenericMethod(params Type[])")]
75+
#endif
6476
public IDisposable? BindCommandToObject<TEventArgs>(ICommand? command, object? target, IObservable<object?> commandParameter, string eventName)
6577
#if MONO
6678
where TEventArgs : EventArgs

src/ReactiveUI/Expression/Reflection.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ public static bool TrySetValueToPropertyChain<TValue>(object? target, IEnumerabl
331331
/// <param name="eventName">The name of the event.</param>
332332
/// <returns>The Type of the EventArgs to use.</returns>
333333
/// <exception cref="Exception">If there is no event matching the name on the target type.</exception>
334+
#if NET6_0_OR_GREATER
335+
[RequiresUnreferencedCode("Calls GetRuntimeMethods()")]
336+
[RequiresDynamicCode("Calls GetRuntimeMethods()")]
337+
#endif
334338
public static Type GetEventArgsTypeForEvent(Type type, string? eventName) // TODO: Create Test
335339
{
336340
type.ArgumentNullExceptionThrowIfNull(nameof(type));
@@ -354,6 +358,10 @@ public static Type GetEventArgsTypeForEvent(Type type, string? eventName) // TOD
354358
/// <param name="targetObject">The object to check.</param>
355359
/// <param name="methodsToCheck">The name of the methods to check.</param>
356360
/// <exception cref="Exception">Thrown if the methods aren't overriden on the target object.</exception>
361+
#if NET6_0_OR_GREATER
362+
[RequiresUnreferencedCode("Calls GetTypeInfo()")]
363+
[RequiresDynamicCode("Calls GetTypeInfo()")]
364+
#endif
357365
public static void ThrowIfMethodsNotOverloaded(string callingTypeName, object targetObject, params string[] methodsToCheck) // TODO: Create Test
358366
{
359367
var (methodName, methodImplementation) = methodsToCheck

src/ReactiveUI/Interfaces/ISuspensionDriver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public interface ISuspensionDriver
1616
/// Loads the application state from persistent storage.
1717
/// </summary>
1818
/// <returns>An object observable.</returns>
19-
IObservable<object> LoadState();
19+
IObservable<object?> LoadState();
2020

2121
/// <summary>
2222
/// Saves the application state to disk.
@@ -30,4 +30,4 @@ public interface ISuspensionDriver
3030
/// </summary>
3131
/// <returns>A completed observable.</returns>
3232
IObservable<Unit> InvalidateState();
33-
}
33+
}

src/ReactiveUI/Mixins/AutoPersistHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace ReactiveUI;
1717
public static class AutoPersistHelper
1818
{
1919
private static readonly MemoizingMRUCache<Type, Dictionary<string, bool>> _persistablePropertiesCache = new(
20-
(type, _) => type.GetTypeInfo().DeclaredProperties
20+
static (type, _) => type.GetTypeInfo().DeclaredProperties
2121
.Where(x => x.CustomAttributes.Any(y => typeof(DataMemberAttribute).GetTypeInfo().IsAssignableFrom(y.AttributeType.GetTypeInfo())))
2222
.ToDictionary(k => k.Name, _ => true),
2323
RxApp.SmallCacheLimit);

src/ReactiveUI/PlatformRegistrationManager.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ namespace ReactiveUI;
1111
public static class PlatformRegistrationManager
1212
{
1313
internal static RegistrationNamespace[] DefaultRegistrationNamespaces { get; } =
14+
#if NET6_0_OR_GREATER
15+
Enum.GetValues<RegistrationNamespace>();
16+
#else
1417
(RegistrationNamespace[])Enum.GetValues(typeof(RegistrationNamespace));
18+
#endif
1519

1620
internal static RegistrationNamespace[] NamespacesToRegister { get; set; } = DefaultRegistrationNamespaces;
1721

@@ -21,4 +25,4 @@ public static class PlatformRegistrationManager
2125
/// </summary>
2226
/// <param name="namespaces">The namespaces to register.</param>
2327
public static void SetRegistrationNamespaces(params RegistrationNamespace[] namespaces) => NamespacesToRegister = namespaces;
24-
}
28+
}

src/ReactiveUI/Platforms/android/BundleSuspensionDriver.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// See the LICENSE file in the project root for full license information.
55

66
using System.IO;
7-
using System.Runtime.Serialization.Formatters.Binary;
7+
using System.Text.Json;
88

99
namespace ReactiveUI;
1010

@@ -14,7 +14,11 @@ namespace ReactiveUI;
1414
public class BundleSuspensionDriver : ISuspensionDriver
1515
{
1616
/// <inheritdoc/>
17-
public IObservable<object> LoadState() // TODO: Create Test
17+
#if NET6_0_OR_GREATER
18+
[RequiresUnreferencedCode("Calls Deserialize<object>()")]
19+
[RequiresDynamicCode("Calls Deserialize<object>()")]
20+
#endif
21+
public IObservable<object?> LoadState() // TODO: Create Test
1822
{
1923
try
2024
{
@@ -24,7 +28,6 @@ public IObservable<object> LoadState() // TODO: Create Test
2428
return Observable.Throw<object>(new Exception("New bundle, start from scratch"));
2529
}
2630

27-
var serializer = new BinaryFormatter();
2831
var buffer = AutoSuspendHelper.LatestBundle.GetByteArray("__state");
2932

3033
if (buffer is null)
@@ -34,7 +37,7 @@ public IObservable<object> LoadState() // TODO: Create Test
3437

3538
var st = new MemoryStream(buffer);
3639

37-
return Observable.Return(serializer.Deserialize(st));
40+
return Observable.Return(JsonSerializer.Deserialize<object>(st));
3841
}
3942
catch (Exception ex)
4043
{
@@ -43,13 +46,16 @@ public IObservable<object> LoadState() // TODO: Create Test
4346
}
4447

4548
/// <inheritdoc/>
49+
#if NET6_0_OR_GREATER
50+
[RequiresUnreferencedCode("Calls Serialize<object>()")]
51+
[RequiresDynamicCode("Calls Serialize<object>()")]
52+
#endif
4653
public IObservable<Unit> SaveState(object state) // TODO: Create Test
4754
{
4855
try
4956
{
50-
var serializer = new BinaryFormatter();
5157
var st = new MemoryStream();
52-
58+
JsonSerializer.Serialize(st, state);
5359
AutoSuspendHelper.LatestBundle?.PutByteArray("__state", st.ToArray());
5460
return Observables.Unit;
5561
}

0 commit comments

Comments
 (0)