Skip to content
Merged
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
16 changes: 8 additions & 8 deletions src/Components/Authorization/src/AuthorizeRouteView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,19 @@ protected override void Render(RenderTreeBuilder builder)
{
// Otherwise, implicitly wrap the output in a <CascadingAuthenticationState>
builder.OpenComponent<CascadingAuthenticationState>(0);
builder.AddAttribute(1, nameof(CascadingAuthenticationState.ChildContent), _renderAuthorizeRouteViewCoreDelegate);
builder.AddComponentParameter(1, nameof(CascadingAuthenticationState.ChildContent), _renderAuthorizeRouteViewCoreDelegate);
builder.CloseComponent();
}
}

private void RenderAuthorizeRouteViewCore(RenderTreeBuilder builder)
{
builder.OpenComponent<AuthorizeRouteViewCore>(0);
builder.AddAttribute(1, nameof(AuthorizeRouteViewCore.RouteData), RouteData);
builder.AddAttribute(2, nameof(AuthorizeRouteViewCore.Authorized), _renderAuthorizedDelegate);
builder.AddAttribute(3, nameof(AuthorizeRouteViewCore.Authorizing), _renderAuthorizingDelegate);
builder.AddAttribute(4, nameof(AuthorizeRouteViewCore.NotAuthorized), _renderNotAuthorizedDelegate);
builder.AddAttribute(5, nameof(AuthorizeRouteViewCore.Resource), Resource);
builder.AddComponentParameter(1, nameof(AuthorizeRouteViewCore.RouteData), RouteData);
builder.AddComponentParameter(2, nameof(AuthorizeRouteViewCore.Authorized), _renderAuthorizedDelegate);
builder.AddComponentParameter(3, nameof(AuthorizeRouteViewCore.Authorizing), _renderAuthorizingDelegate);
builder.AddComponentParameter(4, nameof(AuthorizeRouteViewCore.NotAuthorized), _renderNotAuthorizedDelegate);
builder.AddComponentParameter(5, nameof(AuthorizeRouteViewCore.Resource), Resource);
builder.CloseComponent();
}

Expand All @@ -104,8 +104,8 @@ private void RenderAuthorizeRouteViewCore(RenderTreeBuilder builder)
private void RenderContentInDefaultLayout(RenderTreeBuilder builder, RenderFragment content)
{
builder.OpenComponent<LayoutView>(0);
builder.AddAttribute(1, nameof(LayoutView.Layout), DefaultLayout);
builder.AddAttribute(2, nameof(LayoutView.ChildContent), content);
builder.AddComponentParameter(1, nameof(LayoutView.Layout), DefaultLayout);
builder.AddComponentParameter(2, nameof(LayoutView.ChildContent), content);
builder.CloseComponent();
}

Expand Down
6 changes: 3 additions & 3 deletions src/Components/Authorization/test/AuthorizeRouteViewTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,11 @@ public AuthorizeRouteViewWithExistingCascadedAuthenticationState(
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenComponent<CascadingValue<Task<AuthenticationState>>>(0);
builder.AddAttribute(1, nameof(CascadingValue<object>.Value), _authenticationState);
builder.AddAttribute(2, nameof(CascadingValue<object>.ChildContent), (RenderFragment)(builder =>
builder.AddComponentParameter(1, nameof(CascadingValue<object>.Value), _authenticationState);
builder.AddComponentParameter(2, nameof(CascadingValue<object>.ChildContent), (RenderFragment)(builder =>
{
builder.OpenComponent<AuthorizeRouteView>(0);
builder.AddAttribute(1, nameof(AuthorizeRouteView.RouteData), _routeData);
builder.AddComponentParameter(1, nameof(AuthorizeRouteView.RouteData), _routeData);
builder.CloseComponent();
}));
builder.CloseComponent();
Expand Down
20 changes: 10 additions & 10 deletions src/Components/Authorization/test/AuthorizeViewTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,13 @@ private static TestAuthStateProviderComponent WrapInAuthorizeView(
return new TestAuthStateProviderComponent(builder =>
{
builder.OpenComponent<AuthorizeView>(0);
builder.AddAttribute(1, nameof(AuthorizeView.ChildContent), childContent);
builder.AddAttribute(2, nameof(AuthorizeView.Authorized), authorized);
builder.AddAttribute(3, nameof(AuthorizeView.NotAuthorized), notAuthorized);
builder.AddAttribute(4, nameof(AuthorizeView.Authorizing), authorizing);
builder.AddAttribute(5, nameof(AuthorizeView.Policy), policy);
builder.AddAttribute(6, nameof(AuthorizeView.Roles), roles);
builder.AddAttribute(7, nameof(AuthorizeView.Resource), resource);
builder.AddComponentParameter(1, nameof(AuthorizeView.ChildContent), childContent);
builder.AddComponentParameter(2, nameof(AuthorizeView.Authorized), authorized);
builder.AddComponentParameter(3, nameof(AuthorizeView.NotAuthorized), notAuthorized);
builder.AddComponentParameter(4, nameof(AuthorizeView.Authorizing), authorizing);
builder.AddComponentParameter(5, nameof(AuthorizeView.Policy), policy);
builder.AddComponentParameter(6, nameof(AuthorizeView.Roles), roles);
builder.AddComponentParameter(7, nameof(AuthorizeView.Resource), resource);
builder.CloseComponent();
});
}
Expand All @@ -531,11 +531,11 @@ public TestAuthStateProviderComponent(RenderFragment childContent)
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenComponent<CascadingValue<Task<AuthenticationState>>>(0);
builder.AddAttribute(1, nameof(CascadingValue<Task<AuthenticationState>>.Value), AuthenticationState);
builder.AddAttribute(2, "ChildContent", (RenderFragment)(builder =>
builder.AddComponentParameter(1, nameof(CascadingValue<Task<AuthenticationState>>.Value), AuthenticationState);
builder.AddComponentParameter(2, "ChildContent", (RenderFragment)(builder =>
{
builder.OpenComponent<NeverReRenderComponent>(0);
builder.AddAttribute(1, "ChildContent", _childContent);
builder.AddComponentParameter(1, "ChildContent", _childContent);
builder.CloseComponent();
}));
builder.CloseComponent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class UseCascadingAuthenticationStateComponent : AutoRenderComponent
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenComponent<CascadingAuthenticationState>(0);
builder.AddAttribute(1, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<ReceiveAuthStateComponent>(0);
childBuilder.CloseComponent();
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Components/src/DynamicComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ void Render(RenderTreeBuilder builder)
{
foreach (var entry in Parameters)
{
builder.AddAttribute(1, entry.Key, entry.Value);
builder.AddComponentParameter(1, entry.Key, entry.Value);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Components/Components/src/LayoutView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private static RenderFragment WrapInLayout([DynamicallyAccessedMembers(Component
void Render(RenderTreeBuilder builder)
{
builder.OpenComponent(0, layoutType);
builder.AddAttribute(1, LayoutComponentBase.BodyPropertyName, bodyParam);
builder.AddComponentParameter(1, LayoutComponentBase.BodyPropertyName, bodyParam);
builder.CloseComponent();
};

Expand Down
3 changes: 2 additions & 1 deletion src/Components/Components/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
Microsoft.AspNetCore.Components.ComponentBase.DispatchExceptionAsync(System.Exception! exception) -> System.Threading.Tasks.Task!
Microsoft.AspNetCore.Components.RenderHandle.DispatchExceptionAsync(System.Exception! exception) -> System.Threading.Tasks.Task!
*REMOVED*Microsoft.AspNetCore.Components.NavigationManager.ToAbsoluteUri(string! relativeUri) -> System.Uri!
Microsoft.AspNetCore.Components.NavigationManager.ToAbsoluteUri(string? relativeUri) -> System.Uri!
Microsoft.AspNetCore.Components.NavigationManager.ToAbsoluteUri(string? relativeUri) -> System.Uri!
Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder.AddComponentParameter(int sequence, string! name, object? value) -> void
20 changes: 20 additions & 0 deletions src/Components/Components/src/Rendering/RenderTreeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,18 @@ public void OpenComponent(int sequence, [DynamicallyAccessedMembers(Component)]
OpenComponentUnchecked(sequence, componentType);
}

/// <summary>
/// Appends a frame representing a component parameter.
/// </summary>
/// <param name="sequence">An integer that represents the position of the instruction in the source code.</param>
/// <param name="name">The name of the attribute.</param>
/// <param name="value">The value of the attribute.</param>
public void AddComponentParameter(int sequence, string name, object? value)
Comment thread
MackinnonBuck marked this conversation as resolved.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this approach work when the parameters are splatted?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That calls AddMultipleAttributes(int sequence, IEnumerable<KeyValuePair<string, object>>? attributes) which doesn't have the same overload resolution issue.

If you're suggesting adding a AddMultipleComponentParameters method we could do but it would have no difference in behavior. I agree the aesthetics of still having to use AddMultipleAttributes for components are a bit strange, but if RenderTreeBuilder is only intended as a compiler target it's less of a priority.

{
AssertCanAddComponentParameter();
_entries.AppendAttribute(sequence, name, value);
}

/// <summary>
/// Assigns the specified key value to the current element or component.
/// </summary>
Expand Down Expand Up @@ -649,6 +661,14 @@ private void AssertCanAddAttribute()
}
}

private void AssertCanAddComponentParameter()
{
if (_lastNonAttributeFrameType != RenderTreeFrameType.Component)
{
throw new InvalidOperationException($"Component parameters may only be added immediately after frames of type {RenderTreeFrameType.Component}");
}
}

private int? GetCurrentParentFrameIndex()
=> _openElementIndices.Count == 0 ? (int?)null : _openElementIndices.Peek();

Expand Down
6 changes: 3 additions & 3 deletions src/Components/Components/src/RouteView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ protected virtual void Render(RenderTreeBuilder builder)
?? DefaultLayout;

builder.OpenComponent<LayoutView>(0);
builder.AddAttribute(1, nameof(LayoutView.Layout), pageLayoutType);
builder.AddAttribute(2, nameof(LayoutView.ChildContent), _renderPageWithParametersDelegate);
builder.AddComponentParameter(1, nameof(LayoutView.Layout), pageLayoutType);
builder.AddComponentParameter(2, nameof(LayoutView.ChildContent), _renderPageWithParametersDelegate);
builder.CloseComponent();
}

Expand All @@ -92,7 +92,7 @@ private void RenderPageWithParameters(RenderTreeBuilder builder)

foreach (var kvp in RouteData.RouteValues)
{
builder.AddAttribute(1, kvp.Key, kvp.Value);
builder.AddComponentParameter(1, kvp.Key, kvp.Value);
}

var queryParameterSupplier = QueryParameterValueSupplier.ForType(RouteData.PageType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void RenderParametersFromQueryString(RenderTreeBuilder builder, ReadOnlyM
{
ref var destination = ref _destinations[destinationIndex];
var blankValue = destination.IsArray ? destination.Parser.ParseMultiple(default, string.Empty) : null;
builder.AddAttribute(0, destination.ComponentParameterName, blankValue);
builder.AddComponentParameter(0, destination.ComponentParameterName, blankValue);
}
return;
}
Expand Down Expand Up @@ -101,7 +101,7 @@ public void RenderParametersFromQueryString(RenderTreeBuilder builder, ReadOnlyM
? default
: destination.Parser.Parse(values[0].Span, destination.ComponentParameterName);

builder.AddAttribute(0, destination.ComponentParameterName, parsedValue);
builder.AddComponentParameter(0, destination.ComponentParameterName, parsedValue);
}
}
finally
Expand Down
56 changes: 28 additions & 28 deletions src/Components/Components/test/CascadingParameterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public void PassesCascadingParametersToNestedComponents()
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", "Hello");
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", "Hello");
builder.AddComponentParameter(2, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.AddAttribute(1, "RegularParameter", "Goodbye");
childBuilder.AddComponentParameter(1, "RegularParameter", "Goodbye");
childBuilder.CloseComponent();
}));
builder.CloseComponent();
Expand Down Expand Up @@ -55,11 +55,11 @@ public void RetainsCascadingParametersWhenUpdatingDirectParameters()
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", "Hello");
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", "Hello");
builder.AddComponentParameter(2, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.AddAttribute(1, "RegularParameter", regularParameterValue);
childBuilder.AddComponentParameter(1, "RegularParameter", regularParameterValue);
childBuilder.CloseComponent();
}));
builder.CloseComponent();
Expand Down Expand Up @@ -103,11 +103,11 @@ public void NotifiesDescendantsOfUpdatedCascadingParameterValuesAndPreservesDire
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", providedValue);
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", providedValue);
builder.AddComponentParameter(2, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.AddAttribute(1, "RegularParameter", "Goodbye");
childBuilder.AddComponentParameter(1, "RegularParameter", "Goodbye");
childBuilder.CloseComponent();
}));
builder.CloseComponent();
Expand Down Expand Up @@ -148,11 +148,11 @@ public void DoesNotNotifyDescendantsIfCascadingParameterValuesAreImmutableAndUnc
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", "Unchanging value");
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", "Unchanging value");
builder.AddComponentParameter(2, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.AddAttribute(1, "RegularParameter", "Goodbye");
childBuilder.AddComponentParameter(1, "RegularParameter", "Goodbye");
childBuilder.CloseComponent();
}));
builder.CloseComponent();
Expand Down Expand Up @@ -187,19 +187,19 @@ public void StopsNotifyingDescendantsIfTheyAreRemoved()
{
// At the outer level, have an unrelated fixed cascading value to show we can deal with combining both types
builder.OpenComponent<CascadingValue<int>>(0);
builder.AddAttribute(1, "Value", 123);
builder.AddAttribute(2, "IsFixed", true);
builder.AddAttribute(3, "ChildContent", new RenderFragment(builder2 =>
builder.AddComponentParameter(1, "Value", 123);
builder.AddComponentParameter(2, "IsFixed", true);
builder.AddComponentParameter(3, "ChildContent", new RenderFragment(builder2 =>
{
// Then also have a non-fixed cascading value so we can show that unsubscription works
builder2.OpenComponent<CascadingValue<string>>(0);
builder2.AddAttribute(1, "Value", providedValue);
builder2.AddAttribute(2, "ChildContent", new RenderFragment(builder3 =>
builder2.AddComponentParameter(1, "Value", providedValue);
builder2.AddComponentParameter(2, "ChildContent", new RenderFragment(builder3 =>
{
if (displayNestedComponent)
{
builder3.OpenComponent<SecondCascadingParameterConsumerComponent<string, int>>(0);
builder3.AddAttribute(1, "RegularParameter", "Goodbye");
builder3.AddComponentParameter(1, "RegularParameter", "Goodbye");
builder3.CloseComponent();
}
}));
Expand Down Expand Up @@ -253,14 +253,14 @@ public void DoesNotNotifyDescendantsOfUpdatedCascadingParameterValuesWhenFixed()
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", providedValue);
builder.AddAttribute(2, "IsFixed", true);
builder.AddAttribute(3, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", providedValue);
builder.AddComponentParameter(2, "IsFixed", true);
builder.AddComponentParameter(3, "ChildContent", new RenderFragment(childBuilder =>
{
if (shouldIncludeChild)
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.AddAttribute(1, "RegularParameter", "Goodbye");
childBuilder.AddComponentParameter(1, "RegularParameter", "Goodbye");
childBuilder.CloseComponent();
}
}));
Expand Down Expand Up @@ -312,8 +312,8 @@ public void CascadingValueThrowsIfFixedFlagChangesToTrue()
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<object>>(0);
builder.AddAttribute(1, "IsFixed", isFixed);
builder.AddAttribute(2, "Value", new object());
builder.AddComponentParameter(1, "IsFixed", isFixed);
builder.AddComponentParameter(2, "Value", new object());
builder.CloseComponent();
});
renderer.AssignRootComponentId(component);
Expand All @@ -336,9 +336,9 @@ public void CascadingValueThrowsIfFixedFlagChangesToFalse()
builder.OpenComponent<CascadingValue<object>>(0);
if (isFixed) // Showing also that "unset" is treated as "false"
{
builder.AddAttribute(1, "IsFixed", true);
builder.AddComponentParameter(1, "IsFixed", true);
}
builder.AddAttribute(2, "Value", new object());
builder.AddComponentParameter(2, "Value", new object());
builder.CloseComponent();
});
renderer.AssignRootComponentId(component);
Expand All @@ -359,8 +359,8 @@ public void ParameterViewSuppliedWithCascadingParametersCannotBeUsedAfterSynchro
var component = new TestComponent(builder =>
{
builder.OpenComponent<CascadingValue<string>>(0);
builder.AddAttribute(1, "Value", providedValue);
builder.AddAttribute(2, "ChildContent", new RenderFragment(childBuilder =>
builder.AddComponentParameter(1, "Value", providedValue);
builder.AddComponentParameter(2, "ChildContent", new RenderFragment(childBuilder =>
{
childBuilder.OpenComponent<CascadingParameterConsumerComponent<string>>(0);
childBuilder.CloseComponent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ public ParameterView Build()
{
if (!kvp.Cascading)
{
builder.AddAttribute(1, kvp.Name, kvp.Value);
builder.AddComponentParameter(1, kvp.Name, kvp.Value);
}
}
builder.CloseComponent();
Expand Down
Loading