| File: CascadingValueServiceCollectionExtensions.cs | Web Access |
| Project: src\aspnetcore\src\Components\Components\src\Microsoft.AspNetCore.Components.csproj (Microsoft.AspNetCore.Components) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; using Microsoft.Extensions.DependencyInjection.Extensions; namespace Microsoft.Extensions.DependencyInjection; /// <summary> /// Extension methods for configuring cascading values on an <see cref="IServiceCollection"/>. /// </summary> public static class CascadingValueServiceCollectionExtensions { /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>. This is equivalent to having /// a fixed <see cref="CascadingValue{TValue}"/> at the root of the component hierarchy. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="initialValueFactory">A callback that supplies a fixed value within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static IServiceCollection AddCascadingValue<TValue>( this IServiceCollection serviceCollection, Func<IServiceProvider, TValue> initialValueFactory) => serviceCollection.AddScoped<ICascadingValueSupplier>(sp => new CascadingValueSource<TValue>(() => initialValueFactory(sp), isFixed: true)); /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>. This is equivalent to having /// a fixed <see cref="CascadingValue{TValue}"/> at the root of the component hierarchy. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="name">A name for the cascading value. If set, <see cref="CascadingParameterAttribute"/> can be configured to match based on this name.</param> /// <param name="initialValueFactory">A callback that supplies a fixed value within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static IServiceCollection AddCascadingValue<TValue>( this IServiceCollection serviceCollection, string name, Func<IServiceProvider, TValue> initialValueFactory) => serviceCollection.AddScoped<ICascadingValueSupplier>(sp => new CascadingValueSource<TValue>(name, () => initialValueFactory(sp), isFixed: true)); /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>. This is equivalent to having /// a <see cref="CascadingValue{TValue}"/> at the root of the component hierarchy. /// /// With this overload, you can supply a <see cref="CascadingValueSource{TValue}"/> which allows you /// to notify about updates to the value later, causing recipients to re-render. This overload should /// only be used if you plan to update the value dynamically. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="sourceFactory">A callback that supplies a <see cref="CascadingValueSource{TValue}"/> within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static IServiceCollection AddCascadingValue<TValue>( this IServiceCollection serviceCollection, Func<IServiceProvider, CascadingValueSource<TValue>> sourceFactory) => serviceCollection.AddScoped<ICascadingValueSupplier>(sourceFactory); /// <summary> /// Adds a cascading value supplier to the <paramref name="serviceCollection"/>. This allows supplying cascading values based on custom attributes, which can be used to support multiple cascading values of the same type with different matching criteria. /// </summary> /// <typeparam name="TAttribute">The attribute type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="subscribeFactory">A callback that supplies a <see cref="CascadingParameterSubscription"/> that handles subscriptions for attribute.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static IServiceCollection TryAddCascadingValueSupplier<TAttribute>( this IServiceCollection serviceCollection, Func<IServiceProvider, Func<ComponentState, TAttribute, CascadingParameterInfo, CascadingParameterSubscription>> subscribeFactory) where TAttribute : CascadingParameterAttributeBase { serviceCollection.TryAddEnumerable( ServiceDescriptor.Scoped<ICascadingValueSupplier, CascadingParameterValueProvider<TAttribute>>( sp => new CascadingParameterValueProvider<TAttribute>(subscribeFactory(sp)))); return serviceCollection; } /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered /// with the value type. This is equivalent to having a fixed <see cref="CascadingValue{TValue}"/> at /// the root of the component hierarchy. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="valueFactory">A callback that supplies a fixed value within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static void TryAddCascadingValue<TValue>( this IServiceCollection serviceCollection, Func<IServiceProvider, TValue> valueFactory) { serviceCollection.TryAddEnumerable( ServiceDescriptor.Scoped<ICascadingValueSupplier, CascadingValueSource<TValue>>( sp => new CascadingValueSource<TValue>(() => valueFactory(sp), isFixed: true))); } /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered /// with the value type, regardless of the <paramref name="name"/>. This is equivalent to having a fixed /// <see cref="CascadingValue{TValue}"/> at the root of the component hierarchy. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="name">A name for the cascading value. If set, <see cref="CascadingParameterAttribute"/> can be configured to match based on this name.</param> /// <param name="valueFactory">A callback that supplies a fixed value within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static void TryAddCascadingValue<TValue>( this IServiceCollection serviceCollection, string name, Func<IServiceProvider, TValue> valueFactory) { serviceCollection.TryAddEnumerable( ServiceDescriptor.Scoped<ICascadingValueSupplier, CascadingValueSource<TValue>>( sp => new CascadingValueSource<TValue>(name, () => valueFactory(sp), isFixed: true))); } /// <summary> /// Adds a cascading value to the <paramref name="serviceCollection"/>, if none is already registered /// with the value type. This is equivalent to having a fixed <see cref="CascadingValue{TValue}"/> at /// the root of the component hierarchy. /// /// With this overload, you can supply a <see cref="CascadingValueSource{TValue}"/> which allows you /// to notify about updates to the value later, causing recipients to re-render. This overload should /// only be used if you plan to update the value dynamically. /// </summary> /// <typeparam name="TValue">The value type.</typeparam> /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param> /// <param name="sourceFactory">A callback that supplies a <see cref="CascadingValueSource{TValue}"/> within each service provider scope.</param> /// <returns>The <see cref="IServiceCollection"/>.</returns> public static void TryAddCascadingValue<TValue>( this IServiceCollection serviceCollection, Func<IServiceProvider, CascadingValueSource<TValue>> sourceFactory) { serviceCollection.TryAddEnumerable( ServiceDescriptor.Scoped<ICascadingValueSupplier, CascadingValueSource<TValue>>(sourceFactory)); } }