| File: ViewComponents\DefaultViewComponentFactory.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.ViewFeatures\src\Microsoft.AspNetCore.Mvc.ViewFeatures.csproj (Microsoft.AspNetCore.Mvc.ViewFeatures) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; using System.Reflection; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.Mvc.ViewComponents; /// <summary> /// Default implementation for <see cref="IViewComponentFactory"/>. /// </summary> public class DefaultViewComponentFactory : IViewComponentFactory { private readonly IViewComponentActivator _activator; private readonly Func<Type, PropertyActivator<ViewComponentContext>[]> _getPropertiesToActivate; private readonly ConcurrentDictionary<Type, PropertyActivator<ViewComponentContext>[]> _injectActions; /// <summary> /// Creates a new instance of <see cref="DefaultViewComponentFactory"/> /// </summary> /// <param name="activator"> /// The <see cref="IViewComponentActivator"/> used to create new view component instances. /// </param> public DefaultViewComponentFactory(IViewComponentActivator activator) { ArgumentNullException.ThrowIfNull(activator); _activator = activator; _getPropertiesToActivate = type => PropertyActivator<ViewComponentContext>.GetPropertiesToActivate( type, typeof(ViewComponentContextAttribute), CreateActivateInfo); _injectActions = new ConcurrentDictionary<Type, PropertyActivator<ViewComponentContext>[]>(); } /// <inheritdoc /> public object CreateViewComponent(ViewComponentContext context) { ArgumentNullException.ThrowIfNull(context); var component = _activator.Create(context); InjectProperties(context, component); return component; } private void InjectProperties(ViewComponentContext context, object viewComponent) { var propertiesToActivate = _injectActions.GetOrAdd( viewComponent.GetType(), _getPropertiesToActivate); for (var i = 0; i < propertiesToActivate.Length; i++) { var activateInfo = propertiesToActivate[i]; activateInfo.Activate(viewComponent, context); } } private static PropertyActivator<ViewComponentContext> CreateActivateInfo(PropertyInfo property) { return new PropertyActivator<ViewComponentContext>(property, context => context); } /// <inheritdoc /> public void ReleaseViewComponent(ViewComponentContext context, object component) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(component); _activator.Release(context, component); } /// <inheritdoc /> public ValueTask ReleaseViewComponentAsync(ViewComponentContext context, object component) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(component); return _activator.ReleaseAsync(context, component); } }