| File: Infrastructure\DefaultPageActivatorProvider.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.RazorPages\src\Microsoft.AspNetCore.Mvc.RazorPages.csproj (Microsoft.AspNetCore.Mvc.RazorPages) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq.Expressions; using System.Reflection; using Microsoft.AspNetCore.Mvc.Rendering; namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure; /// <summary> /// <see cref="IPageActivatorProvider"/> that uses type activation to create Pages. /// </summary> internal sealed class DefaultPageActivatorProvider : IPageActivatorProvider { private readonly Action<PageContext, ViewContext, object> _disposer = Dispose; private readonly Func<PageContext, ViewContext, object, ValueTask> _asyncDisposer = AsyncDispose; private readonly Func<PageContext, ViewContext, object, ValueTask> _syncAsyncDisposer = SyncAsyncDispose; /// <inheritdoc /> public Func<PageContext, ViewContext, object> CreateActivator(CompiledPageActionDescriptor actionDescriptor) { ArgumentNullException.ThrowIfNull(actionDescriptor); var pageTypeInfo = actionDescriptor.PageTypeInfo?.AsType(); if (pageTypeInfo == null) { throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull( nameof(actionDescriptor.PageTypeInfo), nameof(actionDescriptor)), nameof(actionDescriptor)); } return CreatePageFactory(pageTypeInfo); } public Action<PageContext, ViewContext, object>? CreateReleaser(CompiledPageActionDescriptor actionDescriptor) { ArgumentNullException.ThrowIfNull(actionDescriptor); if (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(actionDescriptor.PageTypeInfo)) { return _disposer; } return null; } public Func<PageContext, ViewContext, object, ValueTask>? CreateAsyncReleaser(CompiledPageActionDescriptor actionDescriptor) { ArgumentNullException.ThrowIfNull(actionDescriptor); if (typeof(IAsyncDisposable).GetTypeInfo().IsAssignableFrom(actionDescriptor.PageTypeInfo)) { return _asyncDisposer; } if (typeof(IDisposable).GetTypeInfo().IsAssignableFrom(actionDescriptor.PageTypeInfo)) { return _syncAsyncDisposer; } return null; } private static Func<PageContext, ViewContext, object> CreatePageFactory(Type pageTypeInfo) { var parameter1 = Expression.Parameter(typeof(PageContext), "pageContext"); var parameter2 = Expression.Parameter(typeof(ViewContext), "viewContext"); // new Page(); var newExpression = Expression.New(pageTypeInfo); // () => new Page(); var pageFactory = Expression .Lambda<Func<PageContext, ViewContext, object>>(newExpression, parameter1, parameter2) .Compile(); return pageFactory; } private static void Dispose(PageContext context, ViewContext viewContext, object page) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(viewContext); ArgumentNullException.ThrowIfNull(page); ((IDisposable)page).Dispose(); } private static ValueTask SyncAsyncDispose(PageContext context, ViewContext viewContext, object page) { Dispose(context, viewContext, page); return default; } private static ValueTask AsyncDispose(PageContext context, ViewContext viewContext, object page) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(viewContext); ArgumentNullException.ThrowIfNull(page); return ((IAsyncDisposable)page).DisposeAsync(); } }