1- using Extensions . ComponentModel ;
2- using Microsoft . AspNetCore . Components ;
1+ using Microsoft . AspNetCore . Components ;
32using System ;
43using System . Collections . Generic ;
54using System . Linq ;
65using System . Text ;
6+ using System . Reflection ;
7+ using System . Runtime . CompilerServices ;
78using System . Threading . Tasks ;
89
910namespace Blazor . WebForm . UI
1011{
11- internal class EventCallbackAdapter < TValue >
12+ internal class EventCallbackAdapter < TEventArgs , TValue >
1213 {
13- private static readonly Getter < EventCallback < TValue > , MulticastDelegate > GetDelegate = new ComponentOperator ( ) . GetFieldGetter < EventCallback < TValue > , MulticastDelegate > ( "Delegate" ) ;
14- private static readonly Getter < EventCallback < TValue > , IHandleEvent > GetReceiver = new ComponentOperator ( ) . GetFieldGetter < EventCallback < TValue > , IHandleEvent > ( "Receiver" ) ;
14+ [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "Delegate" ) ]
15+ private static extern ref MulticastDelegate GetDelegate ( ref EventCallback < TValue > callback ) ;
16+ [ UnsafeAccessor ( UnsafeAccessorKind . Field , Name = "Receiver" ) ]
17+ private static extern ref IHandleEvent GetReceiver ( ref EventCallback < TValue > callback ) ;
18+ [ UnsafeAccessor ( UnsafeAccessorKind . StaticMethod , Name = "InvokeAsync" ) ]
19+ private static extern Task InvokeAsync < T > ( EventCallbackWorkItem item , MulticastDelegate @delegate , T arg ) ;
1520
16- private readonly EventCallback < TValue > _callback ;
17- private readonly MulticastDelegate _eventHandler ;
21+ private readonly Lazy < Func < object , Task > > _delegateInvoke ;
1822
19- private MulticastDelegate Delegate
20- {
21- get
22- {
23- return GetDelegate ( _callback ) ;
24- }
25- }
26-
27- private IHandleEvent Receiver
23+ public EventCallbackAdapter ( EventCallback < TValue > callback , MulticastDelegate eventHandler )
2824 {
29- get
25+ _delegateInvoke = new Lazy < Func < object , Task > > ( ( ) =>
3026 {
31- return GetReceiver ( _callback ) ;
32- }
27+ EventCallbackWorkItem item = GetItem ( GetDelegate ( ref callback ) , eventHandler ) ;
28+ IHandleEvent receiver = GetReceiver ( ref callback ) ;
29+ if ( receiver != null )
30+ {
31+ return arg => receiver . HandleEventAsync ( item , arg ) ;
32+ }
33+ else
34+ {
35+ return item . InvokeAsync ;
36+ }
37+ } ) ;
3338 }
3439
35- public EventCallbackAdapter ( EventCallback < TValue > callback , MulticastDelegate eventHandler )
40+ public Task InvokeAsync ( TValue value , object sender , TEventArgs e )
3641 {
37- _callback = callback ;
38- _eventHandler = eventHandler ;
42+ return _delegateInvoke . Value . Invoke ( ( value , sender , e ) ) ;
3943 }
4044
41- public Task InvokeAsync ( TValue value , params object [ ] eventArgs )
45+ private static EventCallbackWorkItem GetItem ( MulticastDelegate @delegate , MulticastDelegate eventHandler )
4246 {
43- EventCallbackWorkItem item = new EventCallbackWorkItem ( this . DelegateInvoke ) ;
44- object arg = ( value , eventArgs ) ;
45- IHandleEvent receiver = this . Receiver ;
46- return receiver != null ? receiver . HandleEventAsync ( item , arg ) : item . InvokeAsync ( arg ) ;
47+ Func < object , TEventArgs , Task > invokeAsync = GetInvokeAsync ( eventHandler ) ;
48+ return new EventCallbackWorkItem ( async ( object arg ) =>
49+ {
50+ ( TValue value , object sender , TEventArgs e ) = ( ( TValue , object , TEventArgs ) ) arg ;
51+ await InvokeAsync ( default ( EventCallbackWorkItem ) , @delegate , value ) ;
52+ await invokeAsync . Invoke ( sender , e ) ;
53+ } ) ;
4754 }
4855
49- private void DelegateInvoke ( ( TValue value , object [ ] eventArgs ) arg )
56+ private static Func < object , TEventArgs , Task > GetInvokeAsync ( MulticastDelegate eventHandler )
5057 {
51- this . Delegate ? . DynamicInvoke ( arg . value ) ;
52- _eventHandler ? . DynamicInvoke ( arg . eventArgs ) ;
58+ return eventHandler switch
59+ {
60+ null => ( sender , e ) => Task . CompletedTask ,
61+ EventHandler handler => ( sender , e ) =>
62+ {
63+ handler . Invoke ( sender , e as EventArgs ) ;
64+ return Task . CompletedTask ;
65+ }
66+ ,
67+ EventHandler < TEventArgs > handler => ( sender , e ) =>
68+ {
69+ handler . Invoke ( sender , e ) ;
70+ return Task . CompletedTask ;
71+ }
72+ ,
73+ _ => ( sender , e ) =>
74+ {
75+ try
76+ {
77+ return eventHandler ? . DynamicInvoke ( sender , e ) as Task ?? Task . CompletedTask ;
78+ }
79+ catch ( TargetInvocationException ex )
80+ {
81+ return Task . FromException ( ex . InnerException ) ;
82+ }
83+ }
84+ } ;
5385 }
5486 }
55- }
87+ }
0 commit comments