Skip to content

Commit 17f9810

Browse files
committed
Revert configuration-based approach
1 parent b06b3c4 commit 17f9810

File tree

62 files changed

+474
-503
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+474
-503
lines changed

src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Text.Json;
54
using Microsoft.AspNetCore.Components.RenderTree;
65
using Microsoft.Extensions.Logging;
7-
using Microsoft.Extensions.Options;
86

97
namespace Microsoft.AspNetCore.Components.Infrastructure;
108

@@ -23,25 +21,8 @@ public class ComponentStatePersistenceManager
2321
/// Initializes a new instance of <see cref="ComponentStatePersistenceManager"/>.
2422
/// </summary>
2523
public ComponentStatePersistenceManager(ILogger<ComponentStatePersistenceManager> logger)
26-
: this(DefaultJsonSerializerOptions.Instance, logger)
2724
{
28-
}
29-
30-
/// <summary>
31-
/// Initializes a new instance of <see cref="ComponentStatePersistenceManager"/>.
32-
/// </summary>
33-
public ComponentStatePersistenceManager(
34-
IOptions<JsonOptions> jsonOptions,
35-
ILogger<ComponentStatePersistenceManager> logger)
36-
: this(jsonOptions.Value.SerializerOptions, logger)
37-
{
38-
}
39-
40-
private ComponentStatePersistenceManager(
41-
JsonSerializerOptions jsonSerializerOptions,
42-
ILogger<ComponentStatePersistenceManager> logger)
43-
{
44-
State = new PersistentComponentState(jsonSerializerOptions, _currentState, _registeredCallbacks);
25+
State = new PersistentComponentState(_currentState, _registeredCallbacks);
4526
_logger = logger;
4627
}
4728

src/Components/Components/src/JsonOptions.cs

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/Components/Components/src/JsonServiceCollectionExtensions.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Components/Components/src/Microsoft.AspNetCore.Components.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515

1616
<ItemGroup>
1717
<Compile Include="$(ComponentsSharedSourceRoot)src\ArrayBuilder.cs" LinkBase="RenderTree" />
18-
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultJsonSerializerOptions.cs" />
18+
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerializerOptionsProvider.cs" />
19+
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerializerOptionsCache.cs" />
1920
<Compile Include="$(ComponentsSharedSourceRoot)src\HotReloadManager.cs" LinkBase="HotReload" />
2021
<Compile Include="$(SharedSourceRoot)LinkerFlags.cs" LinkBase="Shared" />
2122
<Compile Include="$(SharedSourceRoot)QueryStringEnumerable.cs" LinkBase="Shared" />

src/Components/Components/src/PersistentComponentState.cs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Diagnostics.CodeAnalysis;
55
using System.Text.Json;
6+
using System.Text.Json.Serialization.Metadata;
67
using static Microsoft.AspNetCore.Internal.LinkerFlags;
78

89
namespace Microsoft.AspNetCore.Components;
@@ -14,15 +15,14 @@ public class PersistentComponentState
1415
{
1516
private IDictionary<string, byte[]>? _existingState;
1617
private readonly IDictionary<string, byte[]> _currentState;
17-
private readonly JsonSerializerOptions _jsonSerializerOptions;
18+
1819
private readonly List<PersistComponentStateRegistration> _registeredCallbacks;
20+
private readonly JsonSerializerOptionsCache _jsonSerializerOptionsCache = new(JsonSerializerOptionsProvider.Options);
1921

2022
internal PersistentComponentState(
21-
JsonSerializerOptions jsonSerializerOptions,
22-
IDictionary<string, byte[]> currentState,
23+
IDictionary<string , byte[]> currentState,
2324
List<PersistComponentStateRegistration> pauseCallbacks)
2425
{
25-
_jsonSerializerOptions = jsonSerializerOptions;
2626
_currentState = currentState;
2727
_registeredCallbacks = pauseCallbacks;
2828
}
@@ -86,7 +86,7 @@ public PersistingComponentStateSubscription RegisterOnPersisting(Func<Task> call
8686
throw new ArgumentException($"There is already a persisted object under the same key '{key}'");
8787
}
8888

89-
_currentState.Add(key, JsonSerializer.SerializeToUtf8Bytes(instance, _jsonSerializerOptions));
89+
_currentState.Add(key, JsonSerializer.SerializeToUtf8Bytes(instance, JsonSerializerOptionsProvider.Options));
9090
}
9191

9292
/// <summary>
@@ -106,7 +106,34 @@ public PersistingComponentStateSubscription RegisterOnPersisting(Func<Task> call
106106
if (TryTake(key, out var data))
107107
{
108108
var reader = new Utf8JsonReader(data);
109-
instance = JsonSerializer.Deserialize<TValue>(ref reader, _jsonSerializerOptions)!;
109+
instance = JsonSerializer.Deserialize<TValue>(ref reader, JsonSerializerOptionsProvider.Options)!;
110+
return true;
111+
}
112+
else
113+
{
114+
instance = default;
115+
return false;
116+
}
117+
}
118+
119+
/// <summary>
120+
/// Tries to retrieve the persisted state as JSON with the given <paramref name="key"/> and deserializes it into an
121+
/// instance of type <typeparamref name="TValue"/>.
122+
/// </summary>
123+
/// <param name="key">The key used to persist the instance.</param>
124+
/// <param name="resolver">The <see cref="IJsonTypeInfoResolver"/> to use when deserializing from JSON.</param>
125+
/// <param name="instance">The persisted instance.</param>
126+
/// <returns><c>true</c> if the state was found; <c>false</c> otherwise.</returns>
127+
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
128+
public bool TryTakeFromJson<TValue>(string key, IJsonTypeInfoResolver resolver, [MaybeNullWhen(false)] out TValue? instance)
129+
{
130+
ArgumentNullException.ThrowIfNull(key);
131+
132+
if (TryTake(key, out var data))
133+
{
134+
var reader = new Utf8JsonReader(data);
135+
var options = _jsonSerializerOptionsCache.GetOrAdd(resolver);
136+
instance = JsonSerializer.Deserialize<TValue>(ref reader, options)!;
110137
return true;
111138
}
112139
else
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
11
#nullable enable
2-
Microsoft.AspNetCore.Components.Infrastructure.ComponentStatePersistenceManager.ComponentStatePersistenceManager(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Components.JsonOptions!>! jsonOptions, Microsoft.Extensions.Logging.ILogger<Microsoft.AspNetCore.Components.Infrastructure.ComponentStatePersistenceManager!>! logger) -> void
3-
Microsoft.AspNetCore.Components.JsonOptions
4-
Microsoft.AspNetCore.Components.JsonOptions.JsonOptions() -> void
5-
Microsoft.AspNetCore.Components.JsonOptions.SerializerOptions.get -> System.Text.Json.JsonSerializerOptions!
6-
Microsoft.Extensions.DependencyInjection.JsonServiceCollectionExtensions
7-
static Microsoft.Extensions.DependencyInjection.JsonServiceCollectionExtensions.ConfigureComponentsJsonOptions(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<Microsoft.AspNetCore.Components.JsonOptions!>! configureOptions) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
2+
Microsoft.AspNetCore.Components.PersistentComponentState.TryTakeFromJson<TValue>(string! key, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver! resolver, out TValue? instance) -> bool

src/Components/Components/test/Lifetime/ComponentApplicationStateTest.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class ComponentApplicationStateTest
1111
public void InitializeExistingState_SetupsState()
1212
{
1313
// Arrange
14-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
14+
var applicationState = new PersistentComponentState(new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
1515
var existingState = new Dictionary<string, byte[]>
1616
{
1717
["MyState"] = JsonSerializer.SerializeToUtf8Bytes(new byte[] { 1, 2, 3, 4 })
@@ -29,7 +29,7 @@ public void InitializeExistingState_SetupsState()
2929
public void InitializeExistingState_ThrowsIfAlreadyInitialized()
3030
{
3131
// Arrange
32-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
32+
var applicationState = new PersistentComponentState(new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
3333
var existingState = new Dictionary<string, byte[]>
3434
{
3535
["MyState"] = new byte[] { 1, 2, 3, 4 }
@@ -45,7 +45,7 @@ public void InitializeExistingState_ThrowsIfAlreadyInitialized()
4545
public void TryRetrieveState_ReturnsStateWhenItExists()
4646
{
4747
// Arrange
48-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
48+
var applicationState = new PersistentComponentState(new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
4949
var existingState = new Dictionary<string, byte[]>
5050
{
5151
["MyState"] = JsonSerializer.SerializeToUtf8Bytes(new byte[] { 1, 2, 3, 4 })
@@ -65,7 +65,7 @@ public void PersistState_SavesDataToTheStoreAsync()
6565
{
6666
// Arrange
6767
var currentState = new Dictionary<string, byte[]>();
68-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, currentState, new List<PersistComponentStateRegistration>())
68+
var applicationState = new PersistentComponentState(currentState, new List<PersistComponentStateRegistration>())
6969
{
7070
PersistingState = true
7171
};
@@ -84,7 +84,7 @@ public void PersistState_ThrowsForDuplicateKeys()
8484
{
8585
// Arrange
8686
var currentState = new Dictionary<string, byte[]>();
87-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, currentState, new List<PersistComponentStateRegistration>())
87+
var applicationState = new PersistentComponentState(currentState, new List<PersistComponentStateRegistration>())
8888
{
8989
PersistingState = true
9090
};
@@ -101,7 +101,7 @@ public void PersistAsJson_SerializesTheDataToJsonAsync()
101101
{
102102
// Arrange
103103
var currentState = new Dictionary<string, byte[]>();
104-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, currentState, new List<PersistComponentStateRegistration>())
104+
var applicationState = new PersistentComponentState(currentState, new List<PersistComponentStateRegistration>())
105105
{
106106
PersistingState = true
107107
};
@@ -120,7 +120,7 @@ public void PersistAsJson_NullValueAsync()
120120
{
121121
// Arrange
122122
var currentState = new Dictionary<string, byte[]>();
123-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, currentState, new List<PersistComponentStateRegistration>())
123+
var applicationState = new PersistentComponentState(currentState, new List<PersistComponentStateRegistration>())
124124
{
125125
PersistingState = true
126126
};
@@ -140,7 +140,7 @@ public void TryRetrieveFromJson_DeserializesTheDataFromJson()
140140
var myState = new byte[] { 1, 2, 3, 4 };
141141
var serialized = JsonSerializer.SerializeToUtf8Bytes(myState);
142142
var existingState = new Dictionary<string, byte[]>() { ["MyState"] = serialized };
143-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
143+
var applicationState = new PersistentComponentState(new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
144144

145145
applicationState.InitializeExistingState(existingState);
146146

@@ -158,7 +158,7 @@ public void TryRetrieveFromJson_NullValue()
158158
// Arrange
159159
var serialized = JsonSerializer.SerializeToUtf8Bytes<byte[]>(null);
160160
var existingState = new Dictionary<string, byte[]>() { ["MyState"] = serialized };
161-
var applicationState = new PersistentComponentState(DefaultJsonSerializerOptions.Instance, new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
161+
var applicationState = new PersistentComponentState(new Dictionary<string, byte[]>(), new List<PersistComponentStateRegistration>());
162162

163163
applicationState.InitializeExistingState(existingState);
164164

src/Components/Server/src/Circuits/RemoteJSRuntime.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ internal partial class RemoteJSRuntime : JSRuntime
4040
public RemoteJSRuntime(
4141
IOptions<CircuitOptions> circuitOptions,
4242
IOptions<HubOptions<ComponentHub>> componentHubOptions,
43-
IOptions<JsonOptions> jsonOptions,
4443
ILogger<RemoteJSRuntime> logger)
4544
{
4645
_options = circuitOptions.Value;
@@ -49,13 +48,6 @@ public RemoteJSRuntime(
4948
DefaultAsyncTimeout = _options.JSInteropDefaultCallTimeout;
5049
ElementReferenceContext = new WebElementReferenceContext(this);
5150
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter(ElementReferenceContext));
52-
53-
JsonSerializerOptions.TypeInfoResolverChain.Add(JsonConverterFactoryTypeInfoResolver.Instance);
54-
55-
if (jsonOptions.Value.SerializerOptions is { TypeInfoResolver: { } typeInfoResolver })
56-
{
57-
JsonSerializerOptions.TypeInfoResolverChain.Add(typeInfoResolver);
58-
}
5951
}
6052

6153
public JsonSerializerOptions ReadJsonSerializerOptions() => JsonSerializerOptions;

src/Components/Server/src/DependencyInjection/ComponentServiceCollectionExtensions.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using Microsoft.AspNetCore.Components.Server.Circuits;
1212
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
1313
using Microsoft.AspNetCore.Components.Web;
14-
using Microsoft.AspNetCore.Components.Web.Infrastructure;
1514
using Microsoft.AspNetCore.SignalR.Protocol;
1615
using Microsoft.Extensions.DependencyInjection.Extensions;
1716
using Microsoft.Extensions.Options;
@@ -88,10 +87,6 @@ public static IServerSideBlazorBuilder AddServerSideBlazor(this IServiceCollecti
8887
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJSInteropDetailedErrorsConfiguration>());
8988
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<CircuitOptions>, CircuitOptionsJavaScriptInitializersConfiguration>());
9089

91-
// Configure JSON serializer options
92-
services.ConfigureComponentsWebJsonOptions();
93-
services.ConfigureDefaultAntiforgeryJsonOptions();
94-
9590
if (configure != null)
9691
{
9792
services.Configure(configure);

src/Components/Server/src/Microsoft.AspNetCore.Components.Server.csproj

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,11 @@
5959
<Compile Include="$(ComponentsSharedSourceRoot)src\RootComponentOperationBatch.cs" />
6060
<Compile Include="$(ComponentsSharedSourceRoot)src\RootComponentOperationType.cs" />
6161
<Compile Include="$(ComponentsSharedSourceRoot)src\RootComponentTypeCache.cs" />
62-
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultJsonSerializerOptions.cs" />
6362
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryStateProvider.cs" LinkBase="Forms" />
64-
<Compile Include="$(ComponentsSharedSourceRoot)src\DefaultAntiforgeryJsonOptionsServiceCollectionExtensions.cs" LinkBase="DependencyInjection" />
6563
<Compile Include="$(ComponentsSharedSourceRoot)src\WebRendererId.cs" />
6664

67-
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerialization\JsonConverterFactoryTypeInfoResolver.cs" LinkBase="JsonSerialization" />
68-
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerialization\JSRuntimeSerializerContext.cs" LinkBase="JsonSerialization" />
69-
7065
<Compile Include="..\..\Shared\src\BrowserNavigationManagerInterop.cs" />
66+
<Compile Include="..\..\Shared\src\JsonSerializerOptionsProvider.cs" />
7167
<Compile Include="..\..\Shared\src\WebEventData\*.cs" LinkBase="WebEventData" />
7268

7369
<Compile Include="$(RepoRoot)src\SignalR\common\Shared\BinaryMessageFormatter.cs" LinkBase="BlazorPack" />

src/Components/Server/src/ProtectedBrowserStorage/ProtectedBrowserStorage.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public abstract class ProtectedBrowserStorage
1616
private readonly string _storeName;
1717
private readonly IJSRuntime _jsRuntime;
1818
private readonly IDataProtectionProvider _dataProtectionProvider;
19-
private readonly JsonSerializerOptions _jsonSerializerOptions;
2019
private readonly ConcurrentDictionary<string, IDataProtector> _cachedDataProtectorsByPurpose
2120
= new ConcurrentDictionary<string, IDataProtector>(StringComparer.Ordinal);
2221

@@ -26,12 +25,7 @@ private readonly ConcurrentDictionary<string, IDataProtector> _cachedDataProtect
2625
/// <param name="storeName">The name of the store in which the data should be stored.</param>
2726
/// <param name="jsRuntime">The <see cref="IJSRuntime"/>.</param>
2827
/// <param name="dataProtectionProvider">The <see cref="IDataProtectionProvider"/>.</param>
29-
/// <param name="jsonSerializerOptions">The <see cref="JsonSerializerOptions"/>.</param>
30-
private protected ProtectedBrowserStorage(
31-
string storeName,
32-
IJSRuntime jsRuntime,
33-
IDataProtectionProvider dataProtectionProvider,
34-
JsonSerializerOptions? jsonSerializerOptions)
28+
private protected ProtectedBrowserStorage(string storeName, IJSRuntime jsRuntime, IDataProtectionProvider dataProtectionProvider)
3529
{
3630
// Performing data protection on the client would give users a false sense of security, so we'll prevent this.
3731
if (OperatingSystem.IsBrowser())
@@ -44,7 +38,6 @@ private protected ProtectedBrowserStorage(
4438
_storeName = storeName;
4539
_jsRuntime = jsRuntime ?? throw new ArgumentNullException(nameof(jsRuntime));
4640
_dataProtectionProvider = dataProtectionProvider ?? throw new ArgumentNullException(nameof(dataProtectionProvider));
47-
_jsonSerializerOptions = jsonSerializerOptions ?? DefaultJsonSerializerOptions.Instance;
4841
}
4942

5043
/// <summary>
@@ -129,7 +122,7 @@ public ValueTask DeleteAsync(string key)
129122

130123
private string Protect(string purpose, object value)
131124
{
132-
var json = JsonSerializer.Serialize(value, options: _jsonSerializerOptions);
125+
var json = JsonSerializer.Serialize(value, options: JsonSerializerOptionsProvider.Options);
133126
var protector = GetOrCreateCachedProtector(purpose);
134127

135128
return protector.Protect(json);
@@ -140,7 +133,7 @@ private TValue Unprotect<TValue>(string purpose, string protectedJson)
140133
var protector = GetOrCreateCachedProtector(purpose);
141134
var json = protector.Unprotect(protectedJson);
142135

143-
return JsonSerializer.Deserialize<TValue>(json, options: _jsonSerializerOptions)!;
136+
return JsonSerializer.Deserialize<TValue>(json, options: JsonSerializerOptionsProvider.Options)!;
144137
}
145138

146139
private ValueTask SetProtectedJsonAsync(string key, string protectedJson)

0 commit comments

Comments
 (0)