Skip to content

Add default implementations for new interface methods in Blazor JS interop #61850

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public interface IInternalWebJSInProcessRuntime
/// <summary>
/// For internal framework use only.
/// </summary>
string InvokeJS(in JSInvocationInfo invocationInfo);
string InvokeJS(in JSInvocationInfo invocationInfo)
=> throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public interface IJSInProcessObjectReference : IJSObjectReference, IDisposable
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSInProcessObjectReference"/> instance that represents the created JS object.</returns>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
IJSInProcessObjectReference InvokeNew(string identifier, object?[]? args);
IJSInProcessObjectReference InvokeNew(string identifier, object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property synchronously.
Expand All @@ -37,7 +38,8 @@ public interface IJSInProcessObjectReference : IJSObjectReference, IDisposable
/// <param name="identifier">An identifier for the property to read. For example, the value <c>"someScope.someProp"</c> will read the value of the property <c>window.someScope.someProp</c>.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
TValue GetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier);
TValue GetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property synchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -46,5 +48,6 @@ public interface IJSInProcessObjectReference : IJSObjectReference, IDisposable
/// <param name="identifier">An identifier for the property to set. For example, the value <c>"someScope.someProp"</c> will update the property <c>window.someScope.someProp</c>.</param>
/// <param name="value">JSON-serializable value.</param>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
void SetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value);
void SetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value)
=> throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public interface IJSInProcessRuntime : IJSRuntime
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSObjectReference"/> instance that represents the created JS object.</returns>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
IJSInProcessObjectReference InvokeNew(string identifier, params object?[]? args);
IJSInProcessObjectReference InvokeNew(string identifier, params object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property synchronously.
Expand All @@ -37,7 +38,8 @@ public interface IJSInProcessRuntime : IJSRuntime
/// <param name="identifier">An identifier for the property to read. For example, the value <c>"someScope.someProp"</c> will read the value of the property <c>window.someScope.someProp</c>.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
TValue GetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier);
TValue GetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property synchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -46,5 +48,6 @@ public interface IJSInProcessRuntime : IJSRuntime
/// <param name="identifier">An identifier for the property to set. For example, the value <c>"someScope.someProp"</c> will update the property <c>window.someScope.someProp</c>.</param>
/// <param name="value">JSON-serializable value.</param>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
void SetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value);
void SetValue<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value)
=> throw new NotImplementedException();
}
18 changes: 12 additions & 6 deletions src/JSInterop/Microsoft.JSInterop/src/IJSObjectReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public interface IJSObjectReference : IAsyncDisposable
/// <param name="identifier">An identifier for the constructor function to invoke. For example, the value <c>"someScope.SomeClass"</c> will invoke the constructor <c>someScope.SomeClass</c> on the target instance.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSObjectReference"/> instance that represents the created JS object.</returns>
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, object?[]? args);
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Invokes the specified JavaScript constructor function asynchronously. The function is invoked with the <c>new</c> operator.
Expand All @@ -55,15 +56,17 @@ public interface IJSObjectReference : IAsyncDisposable
/// </param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSObjectReference"/> instance that represents the created JS object.</returns>
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, CancellationToken cancellationToken, object?[]? args);
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, CancellationToken cancellationToken, object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property asynchronously.
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <param name="identifier">An identifier for the property to read. For example, the value <c>"someScope.someProp"</c> will read the value of the property <c>someScope.someProp</c> on the target instance.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier);
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property asynchronously.
Expand All @@ -75,7 +78,8 @@ public interface IJSObjectReference : IAsyncDisposable
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, CancellationToken cancellationToken);
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, CancellationToken cancellationToken)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property asynchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -84,7 +88,8 @@ public interface IJSObjectReference : IAsyncDisposable
/// <param name="identifier">An identifier for the property to set. For example, the value <c>"someScope.someProp"</c> will update the property <c>someScope.someProp</c> on the target instance.</param>
/// <param name="value">JSON-serializable value.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value);
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property asynchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -97,5 +102,6 @@ public interface IJSObjectReference : IAsyncDisposable
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value, CancellationToken cancellationToken);
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value, CancellationToken cancellationToken)
=> throw new NotImplementedException();
}
18 changes: 12 additions & 6 deletions src/JSInterop/Microsoft.JSInterop/src/IJSRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public interface IJSRuntime
/// <param name="identifier">An identifier for the constructor function to invoke. For example, the value <c>"someScope.SomeClass"</c> will invoke the constructor <c>window.someScope.SomeClass</c>.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSObjectReference"/> instance that represents the created JS object.</returns>
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, object?[]? args);
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Invokes the specified JavaScript constructor function asynchronously. The function is invoked with the <c>new</c> operator.
Expand All @@ -55,15 +56,17 @@ public interface IJSRuntime
/// </param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An <see cref="IJSObjectReference"/> instance that represents the created JS object.</returns>
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, CancellationToken cancellationToken, object?[]? args);
ValueTask<IJSObjectReference> InvokeNewAsync(string identifier, CancellationToken cancellationToken, object?[]? args)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property asynchronously.
/// </summary>
/// <typeparam name="TValue">The JSON-serializable return type.</typeparam>
/// <param name="identifier">An identifier for the property to read. For example, the value <c>"someScope.someProp"</c> will read the value of the property <c>window.someScope.someProp</c>.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier);
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier)
=> throw new NotImplementedException();

/// <summary>
/// Reads the value of the specified JavaScript property asynchronously.
Expand All @@ -75,7 +78,8 @@ public interface IJSRuntime
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, CancellationToken cancellationToken);
ValueTask<TValue> GetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, CancellationToken cancellationToken)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property asynchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -84,7 +88,8 @@ public interface IJSRuntime
/// <param name="identifier">An identifier for the property to set. For example, the value <c>"someScope.someProp"</c> will update the property <c>window.someScope.someProp</c>.</param>
/// <param name="value">JSON-serializable value.</param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value);
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value)
=> throw new NotImplementedException();

/// <summary>
/// Updates the value of the specified JavaScript property asynchronously. If the property is not defined on the target object, it will be created.
Expand All @@ -97,5 +102,6 @@ public interface IJSRuntime
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
/// </param>
/// <returns>A <see cref="ValueTask"/> that represents the asynchronous invocation operation.</returns>
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value, CancellationToken cancellationToken);
ValueTask SetValueAsync<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, TValue value, CancellationToken cancellationToken)
=> throw new NotImplementedException();
}
8 changes: 6 additions & 2 deletions src/JSInterop/Microsoft.JSInterop/src/JSInProcessRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public IJSInProcessObjectReference InvokeNew(string identifier, params object?[]
=> InvokeJS(identifier, argsJson, JSCallResultType.Default, WindowObjectId);

/// <summary>
/// Performs a synchronous function invocation.
/// Performs a synchronous function invocation with the call type <see cref="JSCallType.FunctionCall"/>.
/// For more configuration options, use the overload <see cref="InvokeJS(in JSInvocationInfo)" />.
/// </summary>
/// <param name="identifier">The identifier for the function to invoke.</param>
/// <param name="argsJson">A JSON representation of the arguments.</param>
Expand All @@ -95,5 +96,8 @@ public IJSInProcessObjectReference InvokeNew(string identifier, params object?[]
/// </summary>
/// <param name="invocationInfo">Configuration of the interop call.</param>
/// <returns>A JSON representation of the result.</returns>
protected abstract string? InvokeJS(in JSInvocationInfo invocationInfo);
protected virtual string? InvokeJS(in JSInvocationInfo invocationInfo)
{
return InvokeJS(invocationInfo.Identifier, invocationInfo.ArgsJson, invocationInfo.ResultType, invocationInfo.TargetInstanceId);
}
}
8 changes: 6 additions & 2 deletions src/JSInterop/Microsoft.JSInterop/src/JSRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ protected virtual void BeginInvokeJS(long taskId, string identifier, [StringSynt
=> BeginInvokeJS(taskId, identifier, argsJson, JSCallResultType.Default, WindowObjectId);

/// <summary>
/// Begins an asynchronous function invocation.
/// Begins an asynchronous function invocation with the call type <see cref="JSCallType.FunctionCall"/>.
/// For more configuration options, use the overload <see cref="BeginInvokeJS(in JSInvocationInfo)" />.
/// </summary>
/// <param name="taskId">The identifier for the function invocation, or zero if no async callback is required.</param>
/// <param name="identifier">The identifier for the function to invoke.</param>
Expand All @@ -205,7 +206,10 @@ protected virtual void BeginInvokeJS(long taskId, string identifier, [StringSynt
/// Begins an asynchronous function invocation.
/// </summary>
/// <param name="invocationInfo">Configuration of the interop call from .NET to JavaScript.</param>
protected abstract void BeginInvokeJS(in JSInvocationInfo invocationInfo);
protected virtual void BeginInvokeJS(in JSInvocationInfo invocationInfo)
{
BeginInvokeJS(invocationInfo.AsyncHandle, invocationInfo.Identifier, invocationInfo.ArgsJson, invocationInfo.ResultType, invocationInfo.TargetInstanceId);
}

/// <summary>
/// Completes an async JS interop call from JavaScript to .NET
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#nullable enable
abstract Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> string?
abstract Microsoft.JSInterop.JSRuntime.BeginInvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> void
Microsoft.JSInterop.IJSInProcessObjectReference.GetValue<TValue>(string! identifier) -> TValue
Microsoft.JSInterop.IJSInProcessObjectReference.InvokeNew(string! identifier, object?[]? args) -> Microsoft.JSInterop.IJSInProcessObjectReference!
Microsoft.JSInterop.IJSInProcessObjectReference.SetValue<TValue>(string! identifier, TValue value) -> void
Expand Down Expand Up @@ -62,3 +60,5 @@ static Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeNewAsync(this Micro
static Microsoft.JSInterop.JSRuntimeExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, params object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
static Microsoft.JSInterop.JSRuntimeExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, System.Threading.CancellationToken cancellationToken, object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
static Microsoft.JSInterop.JSRuntimeExtensions.InvokeNewAsync(this Microsoft.JSInterop.IJSRuntime! jsRuntime, string! identifier, System.TimeSpan timeout, object?[]? args) -> System.Threading.Tasks.ValueTask<Microsoft.JSInterop.IJSObjectReference!>
virtual Microsoft.JSInterop.JSInProcessRuntime.InvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> string?
virtual Microsoft.JSInterop.JSRuntime.BeginInvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> void
Loading