-
Notifications
You must be signed in to change notification settings - Fork 10.4k
[Blazor] Add IPersistentComponentStateSerializer<T> interface for custom serialization extensibility #62559
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…bility Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…tionality Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…ementation Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
src/Components/Components/src/IPersistentComponentStateSerializer.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…eedback - Remove CancellationToken from IPersistentComponentStateSerializer interface - Create internal IPersistentComponentStateSerializer base interface with Type parameter - Add default interface implementations for type safety - Add serializer caching with ConcurrentDictionary - Move serializer resolution outside of lambda for better performance - Add PersistAsBytes and TryTakeBytes methods for raw byte operations - Update PublicAPI to reflect interface changes Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
…mination - Changed _serializerCache from static to instance field to prevent different service providers from sharing cached serializers - This ensures each PersistentStateValueProvider instance has its own serializer cache Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
src/Components/Components/src/IPersistentComponentStateSerializer.cs
Outdated
Show resolved
Hide resolved
…review feedback Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
src/Components/Components/src/IPersistentComponentStateSerializer.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/IPersistentComponentStateSerializerOfT.cs
Outdated
Show resolved
Hide resolved
…tract class PersistentComponentStateSerializer<T> Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
src/Components/Components/src/PersistentComponentStateSerializer.cs
Outdated
Show resolved
Hide resolved
|
||
internal interface IPersistentComponentStateSerializer | ||
{ | ||
Task PersistAsync(Type type, object value, IBufferWriter<byte> writer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the task and the async suffix (return void)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interface method is already void returning as requested. This was addressed in a previous commit (0d5d8df).
private IPersistentComponentStateSerializer? ResolveSerializer(Type type) | ||
{ | ||
return _serializerCache.GetOrAdd(type, SerializerFactory); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline this method call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inlined the ResolveSerializer method call at both usage sites and removed the method definition. Commit e922076
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
/// </summary> | ||
/// <param name="value">The value to serialize.</param> | ||
/// <param name="writer">The buffer writer to write the serialized data to.</param> | ||
public abstract void PersistAsync(T value, IBufferWriter<byte> writer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop the async suffix from the method name here and on the base interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dropped the "Async" suffix from both the interface and abstract class method names since they now return void instead of Task. Updated all implementations and tests accordingly. Commit ebe6f52
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
{ | ||
ArgumentNullException.ThrowIfNull(key); | ||
|
||
if (!PersistingState) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These code with checks is shared with PersistAsJson
.
internal void PersistAsBytes(string key, byte[] data)
{
if (PersistanceAllowed(key))
{
_currentState.Add(key, data);
}
}
src/Components/Components/test/IPersistentComponentStateSerializerTests.cs
Show resolved
Hide resolved
/ba-g Unrelated build failures |
This PR implements serialization extensibility for declarative persistent component state, allowing developers to provide custom serializers beyond the built-in JSON serialization.
Changes
New Interface
Key Features
PersistAsync
is async for serialization work, whileRestore
is synchronous to prevent UI tearingIBufferWriter<byte>
withPooledArrayBufferWriter
to minimize allocations, avoidingbyte[]
APIsUsage Example
Register custom serializers in DI:
Components work exactly as before:
Implementation Details
PersistAsync<T>
andTryTake<T>
methods for custom serializersTesting
This enables scenarios like compression, encryption, or optimized binary formats for specific types while maintaining the simple declarative syntax of
[PersistentState]
.Fixes #60716.
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.