| File: Controllers\ControllerActivatorProvider.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.Core\src\Microsoft.AspNetCore.Mvc.Core.csproj (Microsoft.AspNetCore.Mvc.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Reflection; using Microsoft.AspNetCore.Mvc.Core; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Mvc.Controllers; /// <summary> /// Provides methods to create an MVC controller. /// </summary> public class ControllerActivatorProvider : IControllerActivatorProvider { private static readonly Action<ControllerContext, object> _dispose = Dispose; private static readonly Func<ControllerContext, object, ValueTask> _disposeAsync = DisposeAsync; private static readonly Func<ControllerContext, object, ValueTask> _syncDisposeAsync = SyncDisposeAsync; private readonly Func<ControllerContext, object>? _controllerActivatorCreate; private readonly Action<ControllerContext, object>? _controllerActivatorRelease; private readonly Func<ControllerContext, object, ValueTask>? _controllerActivatorReleaseAsync; /// <summary> /// Initializes a new instance of <see cref="ControllerActivatorProvider"/>. /// </summary> /// <param name="controllerActivator">A <see cref="IControllerActivator"/> which is delegated to when not the default implementation.</param> public ControllerActivatorProvider(IControllerActivator controllerActivator) { ArgumentNullException.ThrowIfNull(controllerActivator); // Compat: Delegate to controllerActivator if it's not the default implementation. if (controllerActivator.GetType() != typeof(DefaultControllerActivator)) { _controllerActivatorCreate = controllerActivator.Create; _controllerActivatorRelease = controllerActivator.Release; _controllerActivatorReleaseAsync = controllerActivator.ReleaseAsync; } } /// <inheritdoc/> public Func<ControllerContext, object> CreateActivator(ControllerActionDescriptor descriptor) { ArgumentNullException.ThrowIfNull(descriptor); var controllerType = descriptor.ControllerTypeInfo?.AsType(); if (controllerType == null) { throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( nameof(descriptor.ControllerTypeInfo), nameof(descriptor)), nameof(descriptor)); } if (_controllerActivatorCreate != null) { return _controllerActivatorCreate; } var typeActivator = ActivatorUtilities.CreateFactory(controllerType, Type.EmptyTypes); return controllerContext => typeActivator(controllerContext.HttpContext.RequestServices, arguments: null); } /// <inheritdoc/> public Action<ControllerContext, object>? CreateReleaser(ControllerActionDescriptor descriptor) { ArgumentNullException.ThrowIfNull(descriptor); if (_controllerActivatorRelease != null) { return _controllerActivatorRelease; } if (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(descriptor.ControllerTypeInfo)) { return _dispose; } return null; } /// <inheritdoc/> public Func<ControllerContext, object, ValueTask>? CreateAsyncReleaser(ControllerActionDescriptor descriptor) { ArgumentNullException.ThrowIfNull(descriptor); if (_controllerActivatorReleaseAsync != null) { return _controllerActivatorReleaseAsync; } if (typeof(IAsyncDisposable).GetTypeInfo().IsAssignableFrom(descriptor.ControllerTypeInfo)) { return _disposeAsync; } if (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(descriptor.ControllerTypeInfo)) { return _syncDisposeAsync; } return null; } private static void Dispose(ControllerContext context, object controller) { ArgumentNullException.ThrowIfNull(controller); ((IDisposable)controller).Dispose(); } private static ValueTask DisposeAsync(ControllerContext context, object controller) { ArgumentNullException.ThrowIfNull(controller); return ((IAsyncDisposable)controller).DisposeAsync(); } private static ValueTask SyncDisposeAsync(ControllerContext context, object controller) { Dispose(context, controller); return default; } }