@@ -27,12 +27,13 @@ public static class DotNetDispatcher
2727 /// <summary>
2828 /// Receives a call from JS to .NET, locating and invoking the specified method.
2929 /// </summary>
30+ /// <param name="jsRuntime">The <see cref="JSRuntime"/>.</param>
3031 /// <param name="assemblyName">The assembly containing the method to be invoked.</param>
3132 /// <param name="methodIdentifier">The identifier of the method to be invoked. The method must be annotated with a <see cref="JSInvokableAttribute"/> matching this identifier string.</param>
3233 /// <param name="dotNetObjectId">For instance method calls, identifies the target object.</param>
3334 /// <param name="argsJson">A JSON representation of the parameters.</param>
3435 /// <returns>A JSON representation of the return value, or null.</returns>
35- public static string Invoke ( string assemblyName , string methodIdentifier , long dotNetObjectId , string argsJson )
36+ public static string Invoke ( JSRuntime jsRuntime , string assemblyName , string methodIdentifier , long dotNetObjectId , string argsJson )
3637 {
3738 // This method doesn't need [JSInvokable] because the platform is responsible for having
3839 // some way to dispatch calls here. The logic inside here is the thing that checks whether
@@ -42,41 +43,38 @@ public static string Invoke(string assemblyName, string methodIdentifier, long d
4243 IDotNetObjectReference targetInstance = default ;
4344 if ( dotNetObjectId != default )
4445 {
45- targetInstance = DotNetObjectReferenceManager . Current . FindDotNetObject ( dotNetObjectId ) ;
46+ targetInstance = jsRuntime . GetObjectReference ( dotNetObjectId ) ;
4647 }
4748
48- var syncResult = InvokeSynchronously ( assemblyName , methodIdentifier , targetInstance , argsJson ) ;
49+ var syncResult = InvokeSynchronously ( jsRuntime , assemblyName , methodIdentifier , targetInstance , argsJson ) ;
4950 if ( syncResult == null )
5051 {
5152 return null ;
5253 }
5354
54- return JsonSerializer . Serialize ( syncResult , JsonSerializerOptionsProvider . Options ) ;
55+ return JsonSerializer . Serialize ( syncResult , jsRuntime . JsonSerializerOptions ) ;
5556 }
5657
5758 /// <summary>
5859 /// Receives a call from JS to .NET, locating and invoking the specified method asynchronously.
5960 /// </summary>
61+ /// <param name="jsRuntime">The <see cref="JSRuntime"/>.</param>
6062 /// <param name="callId">A value identifying the asynchronous call that should be passed back with the result, or null if no result notification is required.</param>
6163 /// <param name="assemblyName">The assembly containing the method to be invoked.</param>
6264 /// <param name="methodIdentifier">The identifier of the method to be invoked. The method must be annotated with a <see cref="JSInvokableAttribute"/> matching this identifier string.</param>
6365 /// <param name="dotNetObjectId">For instance method calls, identifies the target object.</param>
6466 /// <param name="argsJson">A JSON representation of the parameters.</param>
6567 /// <returns>A JSON representation of the return value, or null.</returns>
66- public static void BeginInvokeDotNet ( string callId , string assemblyName , string methodIdentifier , long dotNetObjectId , string argsJson )
68+ public static void BeginInvokeDotNet ( JSRuntime jsRuntime , string callId , string assemblyName , string methodIdentifier , long dotNetObjectId , string argsJson )
6769 {
6870 // This method doesn't need [JSInvokable] because the platform is responsible for having
6971 // some way to dispatch calls here. The logic inside here is the thing that checks whether
7072 // the targeted method has [JSInvokable]. It is not itself subject to that restriction,
7173 // because there would be nobody to police that. This method *is* the police.
7274
73- // DotNetDispatcher only works with JSRuntimeBase instances.
74- // If the developer wants to use a totally custom IJSRuntime, then their JS-side
75- // code has to implement its own way of returning async results.
76- var jsRuntimeBaseInstance = ( JSRuntime ) JSRuntime . Current ;
77-
7875 // Using ExceptionDispatchInfo here throughout because we want to always preserve
7976 // original stack traces.
77+
8078 object syncResult = null ;
8179 ExceptionDispatchInfo syncException = null ;
8280 IDotNetObjectReference targetInstance = null ;
@@ -85,10 +83,10 @@ public static void BeginInvokeDotNet(string callId, string assemblyName, string
8583 {
8684 if ( dotNetObjectId != default )
8785 {
88- targetInstance = DotNetObjectReferenceManager . Current . FindDotNetObject ( dotNetObjectId ) ;
86+ targetInstance = jsRuntime . GetObjectReference ( dotNetObjectId ) ;
8987 }
9088
91- syncResult = InvokeSynchronously ( assemblyName , methodIdentifier , targetInstance , argsJson ) ;
89+ syncResult = InvokeSynchronously ( jsRuntime , assemblyName , methodIdentifier , targetInstance , argsJson ) ;
9290 }
9391 catch ( Exception ex )
9492 {
@@ -103,7 +101,7 @@ public static void BeginInvokeDotNet(string callId, string assemblyName, string
103101 else if ( syncException != null )
104102 {
105103 // Threw synchronously, let's respond.
106- jsRuntimeBaseInstance . EndInvokeDotNet ( callId , false , syncException , assemblyName , methodIdentifier , dotNetObjectId ) ;
104+ jsRuntime . EndInvokeDotNet ( callId , false , syncException , assemblyName , methodIdentifier , dotNetObjectId ) ;
107105 }
108106 else if ( syncResult is Task task )
109107 {
@@ -115,20 +113,20 @@ public static void BeginInvokeDotNet(string callId, string assemblyName, string
115113 {
116114 var exception = t . Exception . GetBaseException ( ) ;
117115
118- jsRuntimeBaseInstance . EndInvokeDotNet ( callId , false , ExceptionDispatchInfo . Capture ( exception ) , assemblyName , methodIdentifier , dotNetObjectId ) ;
116+ jsRuntime . EndInvokeDotNet ( callId , false , ExceptionDispatchInfo . Capture ( exception ) , assemblyName , methodIdentifier , dotNetObjectId ) ;
119117 }
120118
121119 var result = TaskGenericsUtil . GetTaskResult ( task ) ;
122- jsRuntimeBaseInstance . EndInvokeDotNet ( callId , true , result , assemblyName , methodIdentifier , dotNetObjectId ) ;
120+ jsRuntime . EndInvokeDotNet ( callId , true , result , assemblyName , methodIdentifier , dotNetObjectId ) ;
123121 } , TaskScheduler . Current ) ;
124122 }
125123 else
126124 {
127- jsRuntimeBaseInstance . EndInvokeDotNet ( callId , true , syncResult , assemblyName , methodIdentifier , dotNetObjectId ) ;
125+ jsRuntime . EndInvokeDotNet ( callId , true , syncResult , assemblyName , methodIdentifier , dotNetObjectId ) ;
128126 }
129127 }
130128
131- private static object InvokeSynchronously ( string assemblyName , string methodIdentifier , IDotNetObjectReference objectReference , string argsJson )
129+ private static object InvokeSynchronously ( JSRuntime jsRuntime , string assemblyName , string methodIdentifier , IDotNetObjectReference objectReference , string argsJson )
132130 {
133131 AssemblyKey assemblyKey ;
134132 if ( objectReference is null )
@@ -154,7 +152,7 @@ private static object InvokeSynchronously(string assemblyName, string methodIden
154152
155153 var ( methodInfo , parameterTypes ) = GetCachedMethodInfo ( assemblyKey , methodIdentifier ) ;
156154
157- var suppliedArgs = ParseArguments ( methodIdentifier , argsJson , parameterTypes ) ;
155+ var suppliedArgs = ParseArguments ( jsRuntime , methodIdentifier , argsJson , parameterTypes ) ;
158156
159157 try
160158 {
@@ -173,7 +171,7 @@ private static object InvokeSynchronously(string assemblyName, string methodIden
173171 }
174172 }
175173
176- internal static object [ ] ParseArguments ( string methodIdentifier , string arguments , Type [ ] parameterTypes )
174+ internal static object [ ] ParseArguments ( JSRuntime jsRuntime , string methodIdentifier , string arguments , Type [ ] parameterTypes )
177175 {
178176 if ( parameterTypes . Length == 0 )
179177 {
@@ -198,7 +196,7 @@ internal static object[] ParseArguments(string methodIdentifier, string argument
198196 throw new InvalidOperationException ( $ "In call to '{ methodIdentifier } ', parameter of type '{ parameterType . Name } ' at index { ( index + 1 ) } must be declared as type 'DotNetObjectRef<{ parameterType . Name } >' to receive the incoming value.") ;
199197 }
200198
201- suppliedArgs [ index ] = JsonSerializer . Deserialize ( ref reader , parameterType , JsonSerializerOptionsProvider . Options ) ;
199+ suppliedArgs [ index ] = JsonSerializer . Deserialize ( ref reader , parameterType , jsRuntime . JsonSerializerOptions ) ;
202200 index ++ ;
203201 }
204202
@@ -247,18 +245,13 @@ static bool IsIncorrectDotNetObjectRefUse(Type parameterType, Utf8JsonReader jso
247245 /// method is responsible for handling any possible exception generated from the arguments
248246 /// passed in as parameters.
249247 /// </remarks>
248+ /// <param name="jsRuntime">The <see cref="JSRuntime"/>.</param>
250249 /// <param name="arguments">The serialized arguments for the callback completion.</param>
251250 /// <exception cref="Exception">
252251 /// This method can throw any exception either from the argument received or as a result
253252 /// of executing any callback synchronously upon completion.
254253 /// </exception>
255- public static void EndInvokeJS ( string arguments )
256- {
257- var jsRuntimeBase = ( JSRuntime ) JSRuntime . Current ;
258- ParseEndInvokeArguments ( jsRuntimeBase , arguments ) ;
259- }
260-
261- internal static void ParseEndInvokeArguments ( JSRuntime jsRuntimeBase , string arguments )
254+ public static void EndInvokeJS ( JSRuntime jsRuntime , string arguments )
262255 {
263256 var utf8JsonBytes = Encoding . UTF8 . GetBytes ( arguments ) ;
264257
@@ -281,7 +274,7 @@ internal static void ParseEndInvokeArguments(JSRuntime jsRuntimeBase, string arg
281274 var success = reader . GetBoolean ( ) ;
282275
283276 reader . Read ( ) ;
284- jsRuntimeBase . EndInvokeJS ( taskId , success , ref reader ) ;
277+ jsRuntime . EndInvokeJS ( taskId , success , ref reader ) ;
285278
286279 if ( ! reader . Read ( ) || reader . TokenType != JsonTokenType . EndArray )
287280 {
0 commit comments