Skip to content

Commit fb52e1a

Browse files
Fix tests by supporting TryAddCascadingValue
1 parent a27e4c4 commit fb52e1a

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

src/Components/Components/src/CascadingValueServiceCollectionExtensions.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Microsoft.AspNetCore.Components;
5+
using Microsoft.Extensions.DependencyInjection.Extensions;
56

67
namespace Microsoft.Extensions.DependencyInjection;
78

@@ -50,4 +51,48 @@ public static IServiceCollection AddCascadingValue<TValue>(
5051
public static IServiceCollection AddCascadingValue<TValue>(
5152
this IServiceCollection serviceCollection, Func<IServiceProvider, CascadingValueSource<TValue>> sourceFactory)
5253
=> serviceCollection.AddScoped<ICascadingValueSupplier>(sourceFactory);
54+
55+
/// <summary>
56+
/// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered
57+
/// with the value type. This is equivalent to having a fixed <see cref="CascadingValue{TValue}"/> at
58+
/// the root of the component hierarchy.
59+
/// </summary>
60+
/// <typeparam name="TValue">The value type.</typeparam>
61+
/// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
62+
/// <param name="valueFactory">A callback that supplies a fixed value within each service provider scope.</param>
63+
/// <returns>The <see cref="IServiceCollection"/>.</returns>
64+
public static void TryAddCascadingValue<TValue>(
65+
this IServiceCollection serviceCollection, Func<IServiceProvider, TValue> valueFactory)
66+
=> serviceCollection.TryAddScoped<ICascadingValueSupplier>(sp => new CascadingValueSource<TValue>(() => valueFactory(sp), isFixed: true));
67+
68+
/// <summary>
69+
/// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered
70+
/// with the value type, regardless of the <paramref name="name"/>. This is equivalent to having a fixed
71+
/// <see cref="CascadingValue{TValue}"/> at the root of the component hierarchy.
72+
/// </summary>
73+
/// <typeparam name="TValue">The value type.</typeparam>
74+
/// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
75+
/// <param name="name">A name for the cascading value. If set, <see cref="CascadingParameterAttribute"/> can be configured to match based on this name.</param>
76+
/// <param name="valueFactory">A callback that supplies a fixed value within each service provider scope.</param>
77+
/// <returns>The <see cref="IServiceCollection"/>.</returns>
78+
public static void TryAddCascadingValue<TValue>(
79+
this IServiceCollection serviceCollection, string name, Func<IServiceProvider, TValue> valueFactory)
80+
=> serviceCollection.TryAddScoped<ICascadingValueSupplier>(sp => new CascadingValueSource<TValue>(name, () => valueFactory(sp), isFixed: true));
81+
82+
/// <summary>
83+
/// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered
84+
/// with the value type. This is equivalent to having a fixed <see cref="CascadingValue{TValue}"/> at
85+
/// the root of the component hierarchy.
86+
///
87+
/// With this overload, you can supply a <see cref="CascadingValueSource{TValue}"/> which allows you
88+
/// to notify about updates to the value later, causing recipients to re-render. This overload should
89+
/// only be used if you plan to update the value dynamically.
90+
/// </summary>
91+
/// <typeparam name="TValue">The value type.</typeparam>
92+
/// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
93+
/// <param name="sourceFactory">A callback that supplies a <see cref="CascadingValueSource{TValue}"/> within each service provider scope.</param>
94+
/// <returns>The <see cref="IServiceCollection"/>.</returns>
95+
public static void TryAddCascadingValue<TValue>(
96+
this IServiceCollection serviceCollection, Func<IServiceProvider, CascadingValueSource<TValue>> sourceFactory)
97+
=> serviceCollection.TryAddScoped<ICascadingValueSupplier>(sourceFactory);
5398
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ static Microsoft.AspNetCore.Components.SupplyParameterFromQueryProviderServiceCo
9191
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, string! name, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
9292
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, Microsoft.AspNetCore.Components.CascadingValueSource<TValue>!>! sourceFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
9393
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.AddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
94+
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.TryAddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, string! name, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> void
95+
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.TryAddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, Microsoft.AspNetCore.Components.CascadingValueSource<TValue>!>! sourceFactory) -> void
96+
static Microsoft.Extensions.DependencyInjection.CascadingValueServiceCollectionExtensions.TryAddCascadingValue<TValue>(this Microsoft.Extensions.DependencyInjection.IServiceCollection! serviceCollection, System.Func<System.IServiceProvider!, TValue>! valueFactory) -> void
9497
virtual Microsoft.AspNetCore.Components.NavigationManager.Refresh(bool forceReload = false) -> void
9598
virtual Microsoft.AspNetCore.Components.Rendering.ComponentState.DisposeAsync() -> System.Threading.Tasks.ValueTask
9699
virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.AddPendingTask(Microsoft.AspNetCore.Components.Rendering.ComponentState? componentState, System.Threading.Tasks.Task! task) -> void

src/Components/Components/test/CascadingParameterTest.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,48 @@ public void OmitsSingleDeliveryCascadingParametersWhenUpdatingDirectParameters()
727727
});
728728
}
729729

730+
[Fact]
731+
public void CanUseTryAddPatternForCascadingValuesInServiceCollection_ValueFactory()
732+
{
733+
// Arrange
734+
var services = new ServiceCollection();
735+
736+
// Act
737+
services.TryAddCascadingValue(_ => new SingleDeliveryValue("first"));
738+
services.TryAddCascadingValue(_ => new SingleDeliveryValue("second"));
739+
740+
// Assert
741+
Assert.Single(services);
742+
}
743+
744+
[Fact]
745+
public void CanUseTryAddPatternForCascadingValuesInServiceCollection_NamedValueFactory()
746+
{
747+
// Arrange
748+
var services = new ServiceCollection();
749+
750+
// Act
751+
services.TryAddCascadingValue("Name1", _ => new SingleDeliveryValue("first"));
752+
services.TryAddCascadingValue("Name2", _ => new SingleDeliveryValue("second"));
753+
754+
// Assert
755+
Assert.Single(services);
756+
}
757+
758+
[Fact]
759+
public void CanUseTryAddPatternForCascadingValuesInServiceCollection_CascadingValueSource()
760+
{
761+
// Arrange
762+
var services = new ServiceCollection();
763+
764+
// Act
765+
services.TryAddCascadingValue(_ => new CascadingValueSource<SingleDeliveryValue>("Name1", new SingleDeliveryValue("first"), false));
766+
services.TryAddCascadingValue(_ => new CascadingValueSource<SingleDeliveryValue>("Name2", new SingleDeliveryValue("second"), false));
767+
768+
// Assert
769+
Assert.Single(services);
770+
}
771+
730772
private class SingleDeliveryValue(string text)
731773
{
732774
public string Text => text;

src/Components/Endpoints/src/DependencyInjection/RazorComponentsServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public static IRazorComponentsBuilder AddRazorComponents(this IServiceCollection
6363
services.TryAddScoped<EndpointRoutingStateProvider>();
6464
services.TryAddScoped<IRoutingStateProvider>(sp => sp.GetRequiredService<EndpointRoutingStateProvider>());
6565
services.AddSupplyValueFromQueryProvider();
66-
services.AddCascadingValue(sp => sp.GetRequiredService<EndpointHtmlRenderer>().HttpContext);
66+
services.TryAddCascadingValue(sp => sp.GetRequiredService<EndpointHtmlRenderer>().HttpContext);
6767

6868
// Form handling
6969
services.AddSupplyValueFromFormProvider();

0 commit comments

Comments
 (0)