public override ValueTask <IActionResult> Execute( IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments) { executor.Execute(controller, arguments); return(new ValueTask <IActionResult>(new EmptyResult())); }
public static Task <object> ExecuteAsync( ObjectMethodExecutor actionMethodExecutor, object instance, IDictionary <string, object> actionArguments) { var orderedArguments = PrepareArguments(actionArguments, actionMethodExecutor.MethodInfo.GetParameters()); return(ExecuteAsync(actionMethodExecutor, instance, orderedArguments)); }
public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments) { // Async method returning awaitable-of-nonvoid var returnValue = await executor.ExecuteAsync(controller, arguments); var actionResult = ConvertToActionResult(returnValue, executor.MethodReturnType); return(actionResult); }
public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments) { // Async method returning awaitable-of-IActionResult (e.g., Task<ViewResult>) // We have to use ExecuteAsync because we don't know the awaitable's type at compile time. var actionResult = (IActionResult)await executor.ExecuteAsync(controller, arguments); EnsureActionResultNotNull(executor, actionResult); return(actionResult); }
public override async ValueTask <IActionResult> Execute(ObjectMethodExecutor executor, object controller, object[] arguments) { // Async method returning Task<IActionResult> // Avoid extra allocations by calling Execute rather than ExecuteAsync and casting to Task<IActionResult>. var returnValue = executor.Execute(controller, arguments); var actionResult = await(Task <IActionResult>) returnValue; EnsureActionResultNotNull(executor, actionResult); return(actionResult); }
public override ValueTask <IActionResult> Execute( IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments) { var actionResult = (IActionResult)executor.Execute(controller, arguments); EnsureActionResultNotNull(executor, actionResult); return(new ValueTask <IActionResult>(actionResult)); }
public override ValueTask <IActionResult> Execute( IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments) { // Sync method returning arbitrary object var returnValue = executor.Execute(controller, arguments); var actionResult = ConvertToActionResult(mapper, returnValue, executor.MethodReturnType); return(new ValueTask <IActionResult>(actionResult)); }
public virtual async Task InvokeAsync() { var cacheEntry = _controllerActionInvokerCache.GetCacheEntry(Context); _filters = _controllerActionInvokerCache.GetFiltersFromEntry(cacheEntry, Context); _controllerActionMethodExecutor = cacheEntry.ActionMethodExecutor; _cursor = new FilterCursor(_filters); Context.ModelState.MaxAllowedErrors = _maxModelValidationErrors; await InvokeAllAuthorizationFiltersAsync(); // If Authorization Filters return a result, it's a short circuit because // authorization failed. We don't execute Result Filters around the result. Debug.Assert(_authorizationContext != null); if (_authorizationContext.Result != null) { await InvokeResultAsync(_authorizationContext.Result); return; } try { await InvokeAllResourceFiltersAsync(); } finally { // Release the instance after all filters have run. We don't need to surround // Authorizations filters because the instance will be created much later than // that. if (Instance != null) { ReleaseInstance(Instance); } } // We've reached the end of resource filters. If there's an unhandled exception on the context then // it should be thrown and middleware has a chance to handle it. Debug.Assert(_resourceExecutedContext != null); if (_resourceExecutedContext.Exception != null && !_resourceExecutedContext.ExceptionHandled) { if (_resourceExecutedContext.ExceptionDispatchInfo == null) { throw _resourceExecutedContext.Exception; } else { _resourceExecutedContext.ExceptionDispatchInfo.Throw(); } } }
public static ActionMethodExecutor GetExecutor(ObjectMethodExecutor executor) { for (var i = 0; i < Executors.Length; i++) { if (Executors[i].CanExecute(executor)) { return(Executors[i]); } } Debug.Fail("Should not get here"); throw new Exception(); }
internal ControllerActionInvokerCacheEntry( FilterItem[] cachedFilters, Func <ControllerContext, object> controllerFactory, Action <ControllerContext, object> controllerReleaser, ControllerBinderDelegate controllerBinderDelegate, ObjectMethodExecutor actionMethodExecutor) { ControllerFactory = controllerFactory; ControllerReleaser = controllerReleaser; ControllerBinderDelegate = controllerBinderDelegate; CachedFilters = cachedFilters; ActionMethodExecutor = actionMethodExecutor; }
private async Task <object> ExecuteAction( Delegate methodDelegate, TestController controller, object[] actionParameters) { var executor = ObjectMethodExecutor.Create(methodDelegate.GetMethodInfo(), _controller.GetType().GetTypeInfo()); var result = await ControllerActionExecutor.ExecuteAsync( executor, controller, actionParameters); return(result); }
public Entry GetCacheEntry(ControllerContext controllerContext) { var cache = CurrentCache; var actionDescriptor = controllerContext.ActionDescriptor; Entry entry; if (cache.Entries.TryGetValue(actionDescriptor, out entry)) { return(entry); } var executor = ObjectMethodExecutor.Create(actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo); var items = new List <FilterItem>(actionDescriptor.FilterDescriptors.Count); for (var i = 0; i < actionDescriptor.FilterDescriptors.Count; i++) { items.Add(new FilterItem(actionDescriptor.FilterDescriptors[i])); } ExecuteProviders(controllerContext, items); var filters = ExtractFilters(items); var allFiltersCached = true; for (var i = 0; i < items.Count; i++) { var item = items[i]; if (!item.IsReusable) { item.Filter = null; allFiltersCached = false; } } if (allFiltersCached) { entry = new Entry(filters, null, executor); } else { entry = new Entry(null, items, executor); } cache.Entries.TryAdd(actionDescriptor, entry); return(entry); }
public (ControllerActionInvokerCacheEntry cacheEntry, IFilterMetadata[] filters) GetCachedResult(ControllerContext controllerContext) { var cache = CurrentCache; var actionDescriptor = controllerContext.ActionDescriptor; IFilterMetadata[] filters; if (!cache.Entries.TryGetValue(actionDescriptor, out var cacheEntry)) { var filterFactoryResult = FilterFactory.GetAllFilters(_filterProviders, controllerContext); filters = filterFactoryResult.Filters; var parameterDefaultValues = ParameterDefaultValues .GetParameterDefaultValues(actionDescriptor.MethodInfo); var objectMethodExecutor = ObjectMethodExecutor.Create( actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo, parameterDefaultValues); var controllerFactory = _controllerFactoryProvider.CreateControllerFactory(actionDescriptor); var controllerReleaser = _controllerFactoryProvider.CreateControllerReleaser(actionDescriptor); var propertyBinderFactory = ControllerBinderDelegateProvider.CreateBinderDelegate( _parameterBinder, _modelBinderFactory, _modelMetadataProvider, actionDescriptor, _mvcOptions); var actionMethodExecutor = ActionMethodExecutor.GetExecutor(objectMethodExecutor); cacheEntry = new ControllerActionInvokerCacheEntry( filterFactoryResult.CacheableFilters, controllerFactory, controllerReleaser, propertyBinderFactory, objectMethodExecutor, actionMethodExecutor); cacheEntry = cache.Entries.GetOrAdd(actionDescriptor, cacheEntry); } else { // Filter instances from statically defined filter descriptors + from filter providers filters = FilterFactory.CreateUncachedFilters(_filterProviders, controllerContext, cacheEntry.CachedFilters); } return(cacheEntry, filters); }
public ControllerActionInvokerState GetState(ControllerContext controllerContext) { // Filter instances from statically defined filter descriptors + from filter providers IFilterMetadata[] filters; var cache = CurrentCache; var actionDescriptor = controllerContext.ActionDescriptor; Entry cacheEntry; if (cache.Entries.TryGetValue(actionDescriptor, out cacheEntry)) { filters = GetFilters(controllerContext, cacheEntry.FilterItems); return(new ControllerActionInvokerState(filters, cacheEntry.ActionMethodExecutor)); } var executor = ObjectMethodExecutor.Create( actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo); var staticFilterItems = new List <FilterItem>(actionDescriptor.FilterDescriptors.Count); for (var i = 0; i < actionDescriptor.FilterDescriptors.Count; i++) { staticFilterItems.Add(new FilterItem(actionDescriptor.FilterDescriptors[i])); } filters = GetFilters(controllerContext, staticFilterItems); // Cache the filter items based on the following criteria // 1. Are created statically (ex: via filter attributes, added to global filter list etc.) // 2. Are re-usable for (var i = 0; i < staticFilterItems.Count; i++) { var item = staticFilterItems[i]; if (!item.IsReusable) { item.Filter = null; } } cacheEntry = new Entry(staticFilterItems, executor); cache.Entries.TryAdd(actionDescriptor, cacheEntry); return(new ControllerActionInvokerState(filters, cacheEntry.ActionMethodExecutor)); }
// Catch-all for sync methods protected override bool CanExecute(ObjectMethodExecutor executor) => !executor.IsMethodAsync;
private bool IsConvertibleToActionResult(ObjectMethodExecutor executor) { var resultType = executor.AsyncResultType ?? executor.MethodReturnType; return(typeof(IConvertToActionResult).IsAssignableFrom(resultType)); }
public Entry(List<FilterItem> items, ObjectMethodExecutor executor) { FilterItems = items; ActionMethodExecutor = executor; }
public static ObjectMethodExecutor Create(MethodInfo methodInfo, TypeInfo targetTypeInfo) { var executor = new ObjectMethodExecutor(methodInfo, targetTypeInfo); return(executor); }
protected override bool CanExecute(ObjectMethodExecutor executor) => !executor.IsMethodAsync && typeof(IActionResult).IsAssignableFrom(executor.MethodReturnType);
public ControllerActionInvoker( ControllerActionInvokerCache cache, IControllerFactory controllerFactory, IControllerArgumentBinder controllerArgumentBinder, ILogger logger, DiagnosticSource diagnosticSource, ActionContext actionContext, IReadOnlyList <IValueProviderFactory> valueProviderFactories, int maxModelValidationErrors) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } if (controllerFactory == null) { throw new ArgumentNullException(nameof(controllerFactory)); } if (controllerArgumentBinder == null) { throw new ArgumentNullException(nameof(controllerArgumentBinder)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } if (diagnosticSource == null) { throw new ArgumentNullException(nameof(diagnosticSource)); } if (actionContext == null) { throw new ArgumentNullException(nameof(actionContext)); } if (valueProviderFactories == null) { throw new ArgumentNullException(nameof(valueProviderFactories)); } _controllerFactory = controllerFactory; _controllerArgumentBinder = controllerArgumentBinder; _logger = logger; _diagnosticSource = diagnosticSource; _controllerContext = new ControllerContext(actionContext); _controllerContext.ModelState.MaxAllowedErrors = maxModelValidationErrors; // PERF: These are rarely going to be changed, so let's go copy-on-write. _controllerContext.ValueProviderFactories = new CopyOnWriteList <IValueProviderFactory>(valueProviderFactories); var cacheEntry = cache.GetState(_controllerContext); _filters = cacheEntry.Filters; _executor = cacheEntry.ActionMethodExecutor; _cursor = new FilterCursor(_filters); }
protected override bool CanExecute(ObjectMethodExecutor executor) => !executor.IsMethodAsync && executor.MethodReturnType == typeof(void);
public abstract ValueTask <IActionResult> Execute( IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments);
protected abstract bool CanExecute(ObjectMethodExecutor executor);
protected override bool CanExecute(ObjectMethodExecutor executor) { // Async method returning awaitable-of - IActionResult(e.g., Task<ViewResult>) return(executor.IsMethodAsync && typeof(IActionResult).IsAssignableFrom(executor.AsyncResultType)); }
protected override bool CanExecute(ObjectMethodExecutor executor) => true;
protected override bool CanExecute(ObjectMethodExecutor executor) => typeof(Task <IActionResult>).IsAssignableFrom(executor.MethodReturnType);
protected override bool CanExecute(ObjectMethodExecutor executor) { // Async method returning void return(executor.IsMethodAsync && executor.AsyncResultType == typeof(void)); }
protected override bool CanExecute(ObjectMethodExecutor executor) => executor.MethodReturnType == typeof(Task);
private static ObjectMethodExecutor CreateExecutor(ControllerActionDescriptor actionDescriptor) { return(ObjectMethodExecutor.Create(actionDescriptor.MethodInfo, actionDescriptor.ControllerTypeInfo)); }
private static bool IsResultIActionResult(ObjectMethodExecutor executor) { var resultType = executor.AsyncResultType ?? executor.MethodReturnType; return(typeof(IActionResult).IsAssignableFrom(resultType)); }