# Grimore Structure ## TODO - IActionDescriptorCollectionProvider ## Action ### ActionContext - ActionContext - LineEventContext - CommandData - ActionDescriptor - ControllerContext - ControllerContext(ActionContext) ### ActionDescriptor - ActionDescriptor - [ActionDescriptor Class (System.Web.Mvc) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.actiondescriptor) - ControllerActionDescriptor ### ActionInvoker - ActionInvoker - InvokeAsync() - ResourceInvoker - ControllerActionInvoker - **ControllerActionInvokerCache** #### ActionInvokerProvider - IActionInvokerProvider - [IActionInvokerProvider Interface (Microsoft.AspNetCore.Mvc.Abstractions) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.abstractions.iactioninvokerprovider) - OnProvidersExecuting(ActionInvokerProviderContext) - OnProvidersExecuted(ActionInvokerProviderContext) - ControllerActionInvokerProvider - OnProvidersExecuting(ActionInvokerProviderContext) - new ControllerContext(ActionInvokerProviderContext.ActionContext) - ControllerActionInvokerCache.GetCachedResult(controllerContext); - ActionInvokerProviderContext.Result = new ControllerActionInvoker ##### ActionInvokerProviderContext - ActionInvokerProviderContext - ActionInvokerProviderContext(ActionContext) - ActionContext - IActionInvoker Result Gets or sets the `IActionInvoker` that will be used to invoke ActionContext #### ActionInvokerFactory - ActionInvokerFactory - IActionInvokerProvider[] `_actionInvokerProviders` - CreateInvoker - new ActionInvokerProviderContext(ActionContext) - foreach `_actionInvokerProviders` .OnProvidersExecuting(ActionInvokerProviderContext) - reversed-foreach `_actionInvokerProviders` .OnProvidersExecuted(ActionInvokerProviderContext) - return ActionInvokerProviderContext.Result # Reference: aspcore structure - IRouter Interface for implementing a router. - public Task RouteAsync(RouteContext context) - Route Builder - Default Handler - Routes - Build() -> IRouter ![](https://images2015.cnblogs.com/blog/250417/201703/250417-20170327154104998-2053909747.png) - Route Handler: IRouter 1. MvcRouteHandler 2. **MvcAttributeRouteHandler** - ActionsAction: Descriptor[] - RouteAsync(RouteContext context) - var actionDescriptor = `_actionSelector`.SelectBestCandidate(context, Actions) - create context.Handler - var routeData = httpContext.GetRouteData(); - var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor); - var invoker = `_actionInvokerFactory`.CreateInvoker(actionContext) - invoker.InvokeAsync() ![](https://images2015.cnblogs.com/blog/250417/201703/250417-20170327220352342-1246687513.png) ### ControllerDescriptor - ControllerName - ControllerType - UniqueId ## Action - ActionContext - HttpContext - RouteData - ActionDescriptorActionDescriptor - ModelStateDictionary ### ActionDescriptor - ActionDescriptor - [ActionDescriptor Class (Microsoft.AspNetCore.Mvc.Abstractions) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.abstractions.actiondescriptor?view=aspnetcore-5.0) - AttributeRouteInfo - Id - Parameters - RouteValues <!-- No need for Grimoire --> - ControllerActionDescriptor - ControllerName - ActionName - MethodInfo - ControllerTypeInfo - CacheEntry #### ActionDescriptorProvider - IActionDescriptorProvider - ActionDescriptors - ControllerActionDescriptorProvider - `internal IEnumerable<ControllerActionDescriptor>` GetDescriptors() - `private IEnumerable<TypeInfo>` GetControllerTypes() - OnProvidersExecuting(ActionDescriptorProviderContext context) - OnProvidersExecuted(ActionDescriptorProviderContext context) #### ActionDescriptorCollectionProvider - ActionDescriptorCollectionProvider - `IReadOnlyList<ActionDescriptor>` ActionDescriptors - DefaultActionDescriptorCollectionProvider - TODO #### ActionDescriptorProviderContext - ActionDescriptorProviderContext - `IList<ActionDescriptor>` Results `{ get; } = new List<ActionDescriptor>();` #### AttributeRouteInfo - AttributeRouteInfo - Order - Template ### ActionInvoker - IActionInvoker - `Task` InvokeAsync() - ResourceInvoker - ControllerActionInvoker - ActionContext - `Task<IActionResult>` ToActionResultAsync(object result) - `static async Task<IActionResult>` ConvertFromTaskAsync`<TValue>(Task<TValue> returnValue, IActionResultTypeMapper mapper)` - `static async Task<IActionResult>` ConvertFromValueTaskAsync`<TValue>( ValueTask<TValue> returnValue, IActionResultTypeMapper mapper)` - `Task` InvokeAsync() - **ControllerActionInvokerCache** #### ActionInvokerFactory - ActionInvokerFactory - IActionInvokerProvider[] `_actionInvokerProviders` - `IActionInvoker` CreateInvoker(ActionContext) - new ActionInvokerProviderContext(ActionContext) - foreach `_actionInvokerProviders` .OnProvidersExecuting(ActionInvokerProviderContext) - reversed-foreach `_actionInvokerProviders` .OnProvidersExecuted(ActionInvokerProviderContext) - return ActionInvokerProviderContext.Result #### ActionInvokerProvider - IActionInvokerProvider - [IActionInvokerProvider Interface (Microsoft.AspNetCore.Mvc.Abstractions) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.abstractions.iactioninvokerprovider) - OnProvidersExecuting(ActionInvokerProviderContext) - OnProvidersExecuted(ActionInvokerProviderContext) - ControllerActionInvokerProvider - OnProvidersExecuting(ActionInvokerProviderContext) - new ControllerContext(ActionInvokerProviderContext.ActionContext) - ControllerActionInvokerCache.GetCachedResult(controllerContext); - ActionInvokerProviderContext.Result = new ControllerActionInvoker ##### ActionInvokerProviderContext - ActionInvokerProviderContext - ActionInvokerProviderContext(ActionContext) - ActionContext - IActionInvoker Result Gets or sets the `IActionInvoker` that will be used to invoke ActionContext ### ActionResult - IActionResult - `Task` ExecuteResultAsync(ActionContext) - ContentResult - NullActionResult Signleton #### IActionResultTypeMapper - IActionResultTypeMapper - `IActionResult` Convert(object value, Type returnType) - ActionResultTypeMapper - => new ContentResult(value.ToString(), "text/plain"); ## ServiceCollectionExtensions - ServiceCollectionExtensions - `IServiceCollection` AddMvcControllers`(this IServiceCollection services)` ```csharp return services .AddSingleton<IActionDescriptorCollectionProvider, DefaultActionDescriptorCollectionProvider>() .AddSingleton<IActionInvokerFactory, ActionInvokerFactory>() .AddSingleton<IActionDescriptorProvider, ControllerActionDescriptorProvider>() .AddSingleton<ControllerActionEndpointDataSource, ControllerActionEndpointDataSource>() .AddSingleton<IActionResultTypeMapper, ActionResultTypeMapper>(); ``` # Others ```csharp= public interface IRouter { Task RouteAsync(RouteContext context); VirtualPathData GetVirtualPath(VirtualPathContext context); } public interface IRouteHandler { RequestDelegate GetRequestHandler(HttpContext httpContext, RouteData routeData); } // Microsoft.AspNetCore.Routing.RouteCollection public async Task Invoke(HttpContext httpContext) { var context = new RouteContext(httpContext); context.RouteData.Routers.Add(_router); await _router.RouteAsync(context); if (context.Handler == null) { _logger.RequestDidNotMatchRoutes(); await _next.Invoke(httpContext); } else { httpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature() { RouteData = context.RouteData, }; await context.Handler(context.HttpContext); } } ``` > Reference: > https://www.cnblogs.com/savorboard/p/aspnetcore-routing.html > https://www.cnblogs.com/savorboard/p/aspnetcore-mvc-routing-action.html > [通过极简模拟框架让你了解ASP.NET Core MVC框架的设计与实现\[上篇\]:路由整合 - Artech - 博客园 (cnblogs.com)](https://www.cnblogs.com/artech/p/inside-asp-net-core-mvc-01.html)