Skip to content

Commit 3f440e2

Browse files
committed
Additional runtime helpers required for component bind:after
1 parent 78616ed commit 3f440e2

File tree

3 files changed

+60
-51
lines changed

3 files changed

+60
-51
lines changed

src/Components/Components/src/CompilerServices/RuntimeHelpers.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +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.Runtime.CompilerServices;
5+
46
namespace Microsoft.AspNetCore.Components.CompilerServices;
57

68
/// <summary>
@@ -67,4 +69,59 @@ public static EventCallback<T> CreateInferredEventCallback<T>(object receiver, E
6769
{
6870
return EventCallback.Factory.Create<T>(receiver, callback);
6971
}
72+
73+
/// <summary>
74+
/// Not intended for use by application code.
75+
/// </summary>
76+
/// <param name="callback"></param>
77+
/// <returns></returns>
78+
//
79+
// This method is used with `@bind-Value:after` for components. When :after is provided we don't know the
80+
// type of the expression provided by the developer or if we can invoke it directly, as it can be a lambda
81+
// and unlike in JavaScript, C# doesn't support Immediately Invoked Function Expressions so we need to pass
82+
// the expression to this helper method and invoke it inside.
83+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
84+
public static void InvokeSynchronousDelegate(Action callback)
85+
{
86+
callback();
87+
}
88+
89+
/// <summary>
90+
/// Not intended for use by application code.
91+
/// </summary>
92+
/// <param name="callback"></param>
93+
/// <returns></returns>
94+
//
95+
// This method is used with `@bind-Value:after` for components. When :after is provided we don't know the
96+
// type of the expression provided by the developer or if we can invoke it directly, as it can be a lambda
97+
// and unlike in JavaScript, C# doesn't support Immediately Invoked Function Expressions so we need to pass
98+
// the expression to this helper method and invoke it inside.
99+
// In addition to that, when the receiving target delegate property result is awaitable, we can receive either
100+
// an Action or a Func<Task> and we don't have that information at compile time, so we use this helper to
101+
// normalize both operations into a Task in the same way we do for EventCallback
102+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
103+
public static Task InvokeAsynchronousDelegate(Action callback)
104+
{
105+
callback();
106+
return Task.CompletedTask;
107+
}
108+
109+
/// <summary>
110+
/// Not intended for use by application code.
111+
/// </summary>
112+
/// <param name="callback"></param>
113+
/// <returns></returns>
114+
//
115+
// This method is used with `@bind-Value:after` for components. When :after is provided we don't know the
116+
// type of the expression provided by the developer or if we can invoke it directly, as it can be a lambda
117+
// and unlike in JavaScript, C# doesn't support Immediately Invoked Function Expressions so we need to pass
118+
// the expression to this helper method and invoke it inside.
119+
// In addition to that, when the receiving target delegate property result is awaitable, we can receive either
120+
// an Action or a Func<Task> and we don't have that information at compile time, so we use this helper to
121+
// normalize both operations into a Task in the same way we do for EventCallback
122+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
123+
public static Task InvokeAsynchronousDelegate(Func<Task> callback)
124+
{
125+
return callback();
126+
}
70127
}

src/Components/Components/src/EventCallbackFactory.cs

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -198,57 +198,6 @@ public EventCallback<TValue> Create<TValue>(object receiver, Func<TValue, Task>
198198
return CreateCore<TValue>(receiver, callback);
199199
}
200200

201-
/// <summary>
202-
/// Creates an <see cref="EventCallback"/> for the provided <paramref name="receiver"/> and
203-
/// <paramref name="callback"/>.
204-
/// </summary>
205-
/// <param name="receiver">The event receiver.</param>
206-
/// <param name="callback">The event callback.</param>
207-
/// <returns>The <see cref="EventCallback"/>.</returns>
208-
public EventCallback<TValue> CreateSetter<TValue>(object receiver, Action<TValue> callback)
209-
{
210-
if (receiver == null)
211-
{
212-
throw new ArgumentNullException(nameof(receiver));
213-
}
214-
215-
return CreateCore<TValue>(receiver, callback);
216-
}
217-
218-
/// <summary>
219-
/// Creates an <see cref="EventCallback"/> for the provided <paramref name="receiver"/> and
220-
/// <paramref name="callback"/>.
221-
/// </summary>
222-
/// <param name="receiver">The event receiver.</param>
223-
/// <param name="callback">The event callback.</param>
224-
/// <returns>The <see cref="EventCallback"/>.</returns>
225-
public EventCallback<TValue> CreateSetter<TValue>(object receiver, Func<TValue, Task> callback)
226-
{
227-
if (receiver == null)
228-
{
229-
throw new ArgumentNullException(nameof(receiver));
230-
}
231-
232-
return CreateCore<TValue>(receiver, callback);
233-
}
234-
235-
/// <summary>
236-
/// Creates an <see cref="EventCallback"/> for the provided <paramref name="receiver"/> and
237-
/// <paramref name="callback"/>.
238-
/// </summary>
239-
/// <param name="receiver">The event receiver.</param>
240-
/// <param name="callback">The event callback.</param>
241-
/// <returns>The <see cref="EventCallback"/>.</returns>
242-
public EventCallback<TValue> CreateSetter<TValue>(object receiver, EventCallback<TValue> callback)
243-
{
244-
if (receiver == null)
245-
{
246-
throw new ArgumentNullException(nameof(receiver));
247-
}
248-
249-
return callback;
250-
}
251-
252201
/// <summary>
253202
/// Creates an <see cref="EventCallback"/> for the provided <paramref name="receiver"/> and
254203
/// <paramref name="callback"/>. For internal framework use only.

src/Components/Components/src/PublicAPI.Unshipped.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#nullable enable
22
Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddContent(int sequence, Microsoft.AspNetCore.Components.MarkupString? markupContent) -> void
33
static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.CreateInferredEventCallback<T>(object! receiver, Microsoft.AspNetCore.Components.EventCallback<T> callback, T value) -> Microsoft.AspNetCore.Components.EventCallback<T>
4+
static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.InvokeAsynchronousDelegate(System.Action! callback) -> System.Threading.Tasks.Task!
5+
static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.InvokeAsynchronousDelegate(System.Func<System.Threading.Tasks.Task!>! callback) -> System.Threading.Tasks.Task!
6+
static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.InvokeSynchronousDelegate(System.Action! callback) -> void
47
static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, Microsoft.AspNetCore.Components.EventCallback<System.DateOnly> setter, System.DateOnly existingValue, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback<Microsoft.AspNetCore.Components.ChangeEventArgs!>
58
static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, Microsoft.AspNetCore.Components.EventCallback<System.DateOnly> setter, System.DateOnly existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback<Microsoft.AspNetCore.Components.ChangeEventArgs!>
69
static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, Microsoft.AspNetCore.Components.EventCallback<System.DateOnly?> setter, System.DateOnly? existingValue, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback<Microsoft.AspNetCore.Components.ChangeEventArgs!>

0 commit comments

Comments
 (0)