/// <inheritdoc />
        public async Task InvokeAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var methodInfo = context.ViewComponentDescriptor?.MethodInfo;
            if (methodInfo == null)
            {
                throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull(
                    nameof(ViewComponentDescriptor.MethodInfo),
                    nameof(ViewComponentDescriptor)));
            }

            var isAsync = typeof(Task).GetTypeInfo().IsAssignableFrom(methodInfo.ReturnType.GetTypeInfo());
            IViewComponentResult result;
            if (isAsync)
            {
                result = await InvokeAsyncCore(context);
            }
            else
            {
                // We support falling back to synchronous if there is no InvokeAsync method, in this case we'll still
                // execute the IViewResult asynchronously.
                result = InvokeSyncCore(context);
            }

            await result.ExecuteAsync(context);
        }
        /// <summary>
        /// Renders JSON text to the output.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        public void Execute(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var serializerSettings = _serializerSettings;
            if (serializerSettings == null)
            {
                serializerSettings = context
                    .ViewContext
                    .HttpContext
                    .RequestServices
                    .GetRequiredService<IOptions<MvcJsonOptions>>()
                    .Value
                    .SerializerSettings;
            }

            using (var jsonWriter = new JsonTextWriter(context.Writer))
            {
                jsonWriter.CloseOutput = false;
                var jsonSerializer = JsonSerializer.Create(serializerSettings);
                jsonSerializer.Serialize(jsonWriter, Value);
            }
        }
        /// <summary>
        /// Encodes and writes the <see cref="Content"/>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        public void Execute(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            context.HtmlEncoder.Encode(context.Writer, Content);
        }
        /// <summary>
        /// Locates and renders a view specified by <see cref="ViewName"/>. If <see cref="ViewName"/> is <c>null</c>,
        /// then the view name searched for is<c>&quot;Default&quot;</c>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/> for the current component execution.</param>
        /// <remarks>
        /// This method synchronously calls and blocks on <see cref="ExecuteAsync(ViewComponentContext)"/>.
        /// </remarks>
        public void Execute(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var task = ExecuteAsync(context);
            task.GetAwaiter().GetResult();
        }
        /// <summary>
        /// Renders JSON text to the output.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        /// <returns>A completed <see cref="Task"/>.</returns>
        public Task ExecuteAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            Execute(context);
            return Task.FromResult(true);
        }
        private SimpleInjectorViewComponentInvoker CreateViewComponentInvoker(ViewComponentContext context)
        {
            IServiceProvider provider = context.ViewContext.HttpContext.RequestServices;

            return new SimpleInjectorViewComponentInvoker(
                provider.GetRequiredService<DiagnosticSource>(),
                provider.GetRequiredService<ILoggerFactory>().CreateLogger<SimpleInjectorViewComponentInvoker>(),
                provider.GetRequiredService<IViewComponentActivator>(),
                this.container);
        }
        /// <inheritdoc />
        // We don't currently make use of the descriptor or the arguments here (they are available on the context).
        // We might do this some day to cache which method we select, so resist the urge to 'clean' this without
        // considering that possibility.
        public IViewComponentInvoker CreateInstance(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            return new DefaultViewComponentInvoker(
                _typeActivatorCache,
                _viewComponentActivator);
        }
        /// <summary>Creates a <see cref="IViewComponentInvoker"/>.</summary>
        /// <param name="context">The context</param>
        /// <returns>A  <see cref="IViewComponentInvoker"/>.</returns>
        public IViewComponentInvoker CreateInstance(ViewComponentContext context)
        {
            Requires.IsNotNull(context, nameof(context));

            if (this.invoker == null)
            {
                this.invoker = this.CreateViewComponentInvoker(context);
            }

            return this.invoker;
        }
 public static void ViewComponentExecuted(
     this ILogger logger,
     ViewComponentContext context,
     int startTime,
     object result)
 {
     var elapsed = new TimeSpan(Environment.TickCount - startTime);
     _viewComponentExecuted(
         logger,
         context.ViewComponentDescriptor.DisplayName,
         elapsed.TotalMilliseconds,
         Convert.ToString(result),
         null);
 }
        public void DefaultViewComponentActivator_ActivatesViewComponentContext()
        {
            // Arrange
            var activator = new DefaultViewComponentActivator();

            var context = new ViewComponentContext();
            var instance = new TestViewComponent();

            // Act
            activator.Activate(instance, context);

            // Assert
            Assert.Same(context, instance.ViewComponentContext);
        }
        public void DefaultViewComponentActivator_ActivatesViewComponentContext_IgnoresNonPublic()
        {
            // Arrange
            var activator = new DefaultViewComponentActivator();

            var context = new ViewComponentContext();
            var instance = new VisibilityViewComponent();

            // Act
            activator.Activate(instance, context);

            // Assert
            Assert.Same(context, instance.ViewComponentContext);
            Assert.Null(instance.C);
        }
 public static void ViewComponentAfterViewExecute(
     this DiagnosticSource diagnosticSource,
     ViewComponentContext context,
     IView view)
 {
     if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewComponentAfterViewExecute"))
     {
         diagnosticSource.Write(
             "Microsoft.AspNet.Mvc.ViewComponentAfterViewExecute",
             new
             {
                 actionDescriptor = context.ViewContext.ActionDescriptor,
                 viewComponentContext = context,
                 view = view
             });
     }
 }
        /// <summary>
        /// Writes the <see cref="EncodedContent"/>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        public void Execute(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var htmlWriter = context.Writer as HtmlTextWriter;
            if (htmlWriter == null)
            {
                EncodedContent.WriteTo(context.Writer, context.HtmlEncoder);
            }
            else
            {
                htmlWriter.Write(EncodedContent);
            }
        }
 public static void BeforeViewComponent(
     this DiagnosticSource diagnosticSource,
     ViewComponentContext context,
     object viewComponent)
 {
     if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.BeforeViewComponent"))
     {
         diagnosticSource.Write(
         "Microsoft.AspNet.Mvc.BeforeViewComponent",
         new
         {
             actionDescriptor = context.ViewContext.ActionDescriptor,
             viewComponentContext = context,
             viewComponent = viewComponent
         });
     }
 }
Example #15
0
        public IViewComponentResult InvokeSyncCore([NotNull] MethodInfo method, [NotNull] ViewComponentContext context)
        {
            var component = CreateComponent(context);

            object result = null;

            try
            {
                result = method.Invoke(component, context.Arguments);
            }
            catch (TargetInvocationException ex)
            {
                // Preserve callstack of any user-thrown exceptions.
                var exceptionInfo = ExceptionDispatchInfo.Capture(ex.InnerException);
                exceptionInfo.Throw();
            }

            return(CoerceToViewComponentResult(result));
        }
Example #16
0
        private async Task <IViewComponentResult> InvokeAsyncCore(
            MethodInfo method,
            ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);

            return(CoerceToViewComponentResult(result));
        }
        public void Invoke(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var method = ViewComponentMethodSelector.FindSyncMethod(
                context.ViewComponentDescriptor.Type.GetTypeInfo(),
                context.Arguments);
            if (method == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatViewComponent_CannotFindMethod(ViewComponentMethodSelector.SyncMethodName));
            }

            var result = InvokeSyncCore(method, context);

            result.Execute(context);
        }
        public IViewComponentResult InvokeSyncCore(MethodInfo method, ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            object result = null;

            using (_logger.ViewComponentScope(context))
            {
                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context);

                try
                {
                    var startTime = Environment.TickCount;
                    result = method.Invoke(component, context.Arguments);

                    var viewComponentResult = CoerceToViewComponentResult(result);
                    _logger.ViewComponentExecuted(context, startTime, viewComponentResult);
                    _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                    return(viewComponentResult);
                }
                catch (TargetInvocationException ex)
                {
                    // Preserve callstack of any user-thrown exceptions.
                    var exceptionInfo = ExceptionDispatchInfo.Capture(ex.InnerException);
                    exceptionInfo.Throw();
                    return(null); // Unreachable
                }
            }
        }
Example #19
0
        public void Invoke(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var method = ViewComponentMethodSelector.FindSyncMethod(
                context.ViewComponentDescriptor.Type.GetTypeInfo(),
                context.Arguments);

            if (method == null)
            {
                throw new InvalidOperationException(
                          Resources.FormatViewComponent_CannotFindMethod(ViewComponentMethodSelector.SyncMethodName));
            }

            var result = InvokeSyncCore(method, context);

            result.Execute(context);
        }
Example #20
0
        /// <inheritdoc />
        public virtual void Activate(object viewComponent, ViewComponentContext context)
        {
            if (viewComponent == null)
            {
                throw new ArgumentNullException(nameof(viewComponent));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var propertiesToActivate = _injectActions.GetOrAdd(
                viewComponent.GetType(),
                _getPropertiesToActivate);

            for (var i = 0; i < propertiesToActivate.Length; i++)
            {
                var activateInfo = propertiesToActivate[i];
                activateInfo.Activate(viewComponent, context);
            }
        }
        private async Task <IViewComponentResult> InvokeAsyncCore(ViewComponentContext context)
        {
            var component = CreateComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                var method    = context.ViewComponentDescriptor.MethodInfo;
                var arguments = ControllerActionExecutor.PrepareArguments(context.Arguments, method.GetParameters());

                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context, arguments);

                var startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0;
                var result         = await ControllerActionExecutor.ExecuteAsync(method, component, arguments);

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTimestamp, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                return(viewComponentResult);
            }
        }
        /// <inheritdoc />
        public virtual void Activate(object viewComponent, ViewComponentContext context)
        {
            if (viewComponent == null)
            {
                throw new ArgumentNullException(nameof(viewComponent));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var propertiesToActivate = _injectActions.GetOrAdd(
                viewComponent.GetType(),
                _getPropertiesToActivate);

            for (var i = 0; i < propertiesToActivate.Length; i++)
            {
                var activateInfo = propertiesToActivate[i];
                activateInfo.Activate(viewComponent, context);
            }
        }
Example #23
0
        public async Task InvokeAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            IViewComponentResult result;

            var asyncMethod = ViewComponentMethodSelector.FindAsyncMethod(
                context.ViewComponentDescriptor.Type.GetTypeInfo(),
                context.Arguments);

            if (asyncMethod == null)
            {
                // We support falling back to synchronous if there is no InvokeAsync method, in this case we'll still
                // execute the IViewResult asynchronously.
                var syncMethod = ViewComponentMethodSelector.FindSyncMethod(
                    context.ViewComponentDescriptor.Type.GetTypeInfo(),
                    context.Arguments);
                if (syncMethod == null)
                {
                    throw new InvalidOperationException(
                              Resources.FormatViewComponent_CannotFindMethod_WithFallback(
                                  ViewComponentMethodSelector.SyncMethodName, ViewComponentMethodSelector.AsyncMethodName));
                }
                else
                {
                    result = InvokeSyncCore(syncMethod, context);
                }
            }
            else
            {
                result = await InvokeAsyncCore(asyncMethod, context);
            }

            await result.ExecuteAsync(context);
        }
        public async Task InvokeAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            IViewComponentResult result;

            var asyncMethod = ViewComponentMethodSelector.FindAsyncMethod(
                context.ViewComponentDescriptor.Type.GetTypeInfo(),
                context.Arguments);
            if (asyncMethod == null)
            {
                // We support falling back to synchronous if there is no InvokeAsync method, in this case we'll still
                // execute the IViewResult asynchronously.
                var syncMethod = ViewComponentMethodSelector.FindSyncMethod(
                    context.ViewComponentDescriptor.Type.GetTypeInfo(),
                    context.Arguments);
                if (syncMethod == null)
                {
                    throw new InvalidOperationException(
                        Resources.FormatViewComponent_CannotFindMethod_WithFallback(
                        ViewComponentMethodSelector.SyncMethodName, ViewComponentMethodSelector.AsyncMethodName));
                }
                else
                {
                    result = InvokeSyncCore(syncMethod, context);
                }
            }
            else
            {
                result = await InvokeAsyncCore(asyncMethod, context);
            }

            await result.ExecuteAsync(context);
        }
 private static IViewEngine ResolveViewEngine(ViewComponentContext context)
 {
     return context.ViewContext.HttpContext.RequestServices.GetRequiredService<ICompositeViewEngine>();
 }
 public static void ViewComponentExecuting(this ILogger logger, ViewComponentContext context)
 {
     _viewComponentExecuting(logger, context.ViewComponentDescriptor.DisplayName, null);
 }
        /// <summary>
        /// Locates and renders a view specified by <see cref="ViewName"/>. If <see cref="ViewName"/> is <c>null</c>,
        /// then the view name searched for is<c>&quot;Default&quot;</c>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/> for the current component execution.</param>
        /// <returns>A <see cref="Task"/> which will complete when view rendering is completed.</returns>
        public async Task ExecuteAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewEngine = ViewEngine ?? ResolveViewEngine(context);
            var viewData = ViewData ?? context.ViewData;
            var isNullOrEmptyViewName = string.IsNullOrEmpty(ViewName);

            string qualifiedViewName;
            if (!isNullOrEmptyViewName &&
                (ViewName[0] == '~' || ViewName[0] == '/'))
            {
                // View name that was passed in is already a rooted path, the view engine will handle this.
                qualifiedViewName = ViewName;
            }
            else
            {
                // This will produce a string like:
                //
                //  Components/Cart/Default
                //
                // The view engine will combine this with other path info to search paths like:
                //
                //  Views/Shared/Components/Cart/Default.cshtml
                //  Views/Home/Components/Cart/Default.cshtml
                //  Areas/Blog/Views/Shared/Components/Cart/Default.cshtml
                //
                // This supports a controller or area providing an override for component views.
                var viewName = isNullOrEmptyViewName ? DefaultViewName : ViewName;

                qualifiedViewName = string.Format(
                    CultureInfo.InvariantCulture,
                    ViewPathFormat,
                    context.ViewComponentDescriptor.ShortName,
                    viewName);
            }

            var view = FindView(context.ViewContext, viewEngine, qualifiedViewName);

            var childViewContext = new ViewContext(
                context.ViewContext,
                view,
                ViewData ?? context.ViewData,
                context.Writer);

            using (view as IDisposable)
            {
                if (_diagnosticSource == null)
                {
                    _diagnosticSource = context.ViewContext.HttpContext.RequestServices.GetRequiredService<DiagnosticSource>();
                }

                _diagnosticSource.ViewComponentBeforeViewExecute(context, view);

                await view.RenderAsync(childViewContext);

                _diagnosticSource.ViewComponentAfterViewExecute(context, view);
            }
        }
        /// <summary>
        /// Encodes and writes the <see cref="Content"/>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        /// <returns>A completed <see cref="Task"/>.</returns>
        public Task ExecuteAsync(ViewComponentContext context)
        {
            Execute(context);

            return TaskCache.CompletedTask;
        }
 private static IViewEngine ResolveViewEngine(ViewComponentContext context)
 {
     return(context.ViewContext.HttpContext.RequestServices.GetRequiredService <ICompositeViewEngine>());
 }
        private void InvokeCore(
            TextWriter writer,
            ViewComponentDescriptor descriptor,
            object[] arguments)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (descriptor == null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer);

            var invoker = _invokerFactory.CreateInstance(context);
            if (invoker == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatViewComponent_IViewComponentFactory_ReturnedNull(descriptor.Type.FullName));
            }

            invoker.Invoke(context);
        }
        /// <summary>
        /// Locates and renders a view specified by <see cref="ViewName"/>. If <see cref="ViewName"/> is <c>null</c>,
        /// then the view name searched for is<c>&quot;Default&quot;</c>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/> for the current component execution.</param>
        /// <returns>A <see cref="Task"/> which will complete when view rendering is completed.</returns>
        public async Task ExecuteAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewEngine            = ViewEngine ?? ResolveViewEngine(context);
            var viewContext           = context.ViewContext;
            var viewData              = ViewData ?? context.ViewData;
            var isNullOrEmptyViewName = string.IsNullOrEmpty(ViewName);

            ViewEngineResult     result            = null;
            IEnumerable <string> originalLocations = null;

            if (!isNullOrEmptyViewName)
            {
                // If view name was passed in is already a path, the view engine will handle this.
                result            = viewEngine.GetView(viewContext.ExecutingFilePath, ViewName, isMainPage: false);
                originalLocations = result.SearchedLocations;
            }

            if (result == null || !result.Success)
            {
                // This will produce a string like:
                //
                //  Components/Cart/Default
                //
                // The view engine will combine this with other path info to search paths like:
                //
                //  Views/Shared/Components/Cart/Default.cshtml
                //  Views/Home/Components/Cart/Default.cshtml
                //  Areas/Blog/Views/Shared/Components/Cart/Default.cshtml
                //
                // This supports a controller or area providing an override for component views.
                var viewName          = isNullOrEmptyViewName ? DefaultViewName : ViewName;
                var qualifiedViewName = string.Format(
                    CultureInfo.InvariantCulture,
                    ViewPathFormat,
                    context.ViewComponentDescriptor.ShortName,
                    viewName);

                result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
            }

            var view = result.EnsureSuccessful(originalLocations).View;

            using (view as IDisposable)
            {
                if (_diagnosticSource == null)
                {
                    _diagnosticSource = viewContext.HttpContext.RequestServices.GetRequiredService <DiagnosticSource>();
                }

                _diagnosticSource.ViewComponentBeforeViewExecute(context, view);

                var childViewContext = new ViewContext(
                    viewContext,
                    view,
                    ViewData ?? context.ViewData,
                    context.Writer);
                await view.RenderAsync(childViewContext);

                _diagnosticSource.ViewComponentAfterViewExecute(context, view);
            }
        }
        public IViewComponentResult InvokeSyncCore(MethodInfo method, ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            object result = null;

            using (_logger.ViewComponentScope(context))
            {
                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context);

                try
                {
                    var startTime = Environment.TickCount;
                    result = method.Invoke(component, context.Arguments);

                    var viewComponentResult = CoerceToViewComponentResult(result);
                    _logger.ViewComponentExecuted(context, startTime, viewComponentResult);
                    _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                    return viewComponentResult;
                }
                catch (TargetInvocationException ex)
                {
                    // Preserve callstack of any user-thrown exceptions.
                    var exceptionInfo = ExceptionDispatchInfo.Capture(ex.InnerException);
                    exceptionInfo.Throw();
                    return null; // Unreachable
                }
            }
        }
        protected virtual object CreateComponent(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var services = context.ViewContext.HttpContext.RequestServices;
            var component = _typeActivatorCache.CreateInstance<object>(
                services,
                context.ViewComponentDescriptor.Type);
            _viewComponentActivator.Activate(component, context);
            return component;
        }
        /// <summary>
        /// Writes the <see cref="EncodedContent"/>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/>.</param>
        /// <returns>A completed <see cref="Task"/>.</returns>
        public Task ExecuteAsync(ViewComponentContext context)
        {
            Execute(context);

            return(TaskCache.CompletedTask);
        }
        private async Task<IHtmlContent> InvokeCoreAsync(
            ViewComponentDescriptor descriptor,
            object arguments)
        {
            var viewBuffer = new ViewBuffer(_viewBufferScope, descriptor.FullName);
            using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _viewContext.Writer.Encoding))
            {
                var context = new ViewComponentContext(
                    descriptor,
                    PropertyHelper.ObjectToDictionary(arguments),
                    _htmlEncoder,
                    _viewContext,
                    writer);

                var invoker = _invokerFactory.CreateInstance(context);
                if (invoker == null)
                {
                    throw new InvalidOperationException(
                        Resources.FormatViewComponent_IViewComponentFactory_ReturnedNull(descriptor.FullName));
                }

                await invoker.InvokeAsync(context);
                return writer.ContentBuilder;
            }
        }
 public static IDisposable ViewComponentScope(this ILogger logger, ViewComponentContext context)
 {
     return logger.BeginScopeImpl(new ViewComponentLogScope(context.ViewComponentDescriptor));
 }
        private async Task<IViewComponentResult> InvokeAsyncCore(
            MethodInfo method,
            ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context);

                var startTime = Environment.TickCount;
                var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTime, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                return viewComponentResult;
            }
        }
Example #38
0
 /// <inheritdoc />
 // We don't currently make use of the descriptor or the arguments here (they are available on the context).
 // We might do this some day to cache which method we select, so resist the urge to 'clean' this without
 // considering that possibility.
 public IViewComponentInvoker CreateInstance([NotNull] ViewComponentContext context)
 {
     return(new DefaultViewComponentInvoker(
                _typeActivatorCache,
                _viewComponentActivator));
 }
Example #39
0
        /// <summary>
        /// Locates and renders a view specified by <see cref="ViewName"/>. If <see cref="ViewName"/> is <c>null</c>,
        /// then the view name searched for is<c>&quot;Default&quot;</c>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/> for the current component execution.</param>
        /// <returns>A <see cref="Task"/> which will complete when view rendering is completed.</returns>
        public async Task ExecuteAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewEngine            = ViewEngine ?? ResolveViewEngine(context);
            var viewData              = ViewData ?? context.ViewData;
            var isNullOrEmptyViewName = string.IsNullOrEmpty(ViewName);

            string qualifiedViewName;

            if (!isNullOrEmptyViewName &&
                (ViewName[0] == '~' || ViewName[0] == '/'))
            {
                // View name that was passed in is already a rooted path, the view engine will handle this.
                qualifiedViewName = ViewName;
            }
            else
            {
                // This will produce a string like:
                //
                //  Components/Cart/Default
                //
                // The view engine will combine this with other path info to search paths like:
                //
                //  Views/Shared/Components/Cart/Default.cshtml
                //  Views/Home/Components/Cart/Default.cshtml
                //  Areas/Blog/Views/Shared/Components/Cart/Default.cshtml
                //
                // This supports a controller or area providing an override for component views.
                var viewName = isNullOrEmptyViewName ? DefaultViewName : ViewName;

                qualifiedViewName = string.Format(
                    CultureInfo.InvariantCulture,
                    ViewPathFormat,
                    context.ViewComponentDescriptor.ShortName,
                    viewName);
            }

            var view = FindView(context.ViewContext, viewEngine, qualifiedViewName);

            var childViewContext = new ViewContext(
                context.ViewContext,
                view,
                ViewData ?? context.ViewData,
                context.Writer);

            using (view as IDisposable)
            {
                if (_diagnosticSource == null)
                {
                    _diagnosticSource = context.ViewContext.HttpContext.RequestServices.GetRequiredService <DiagnosticSource>();
                }

                _diagnosticSource.ViewComponentBeforeViewExecute(context, view);

                await view.RenderAsync(childViewContext);

                _diagnosticSource.ViewComponentAfterViewExecute(context, view);
            }
        }
 protected override object CreateComponent(ViewComponentContext context)
 {
     var component = this.container.GetInstance(context.ViewComponentDescriptor.Type);
     this.viewComponentActivator.Activate(component, context);
     return component;
 }
        private async Task InvokeCoreAsync(
            [NotNull] TextWriter writer,
            [NotNull] ViewComponentDescriptor descriptor,
            object[] arguments)
        {
            var invoker = _invokerFactory.CreateInstance(descriptor, arguments);
            if (invoker == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatViewComponent_IViewComponentFactory_ReturnedNull(descriptor.Type.FullName));
            }

            var context = new ViewComponentContext(descriptor, arguments, _viewContext, writer);
            await invoker.InvokeAsync(context);
        }
        /// <summary>
        /// Locates and renders a view specified by <see cref="ViewName"/>. If <see cref="ViewName"/> is <c>null</c>,
        /// then the view name searched for is<c>&quot;Default&quot;</c>.
        /// </summary>
        /// <param name="context">The <see cref="ViewComponentContext"/> for the current component execution.</param>
        /// <returns>A <see cref="Task"/> which will complete when view rendering is completed.</returns>
        public async Task ExecuteAsync(ViewComponentContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewEngine = ViewEngine ?? ResolveViewEngine(context);
            var viewContext = context.ViewContext;
            var viewData = ViewData ?? context.ViewData;
            var isNullOrEmptyViewName = string.IsNullOrEmpty(ViewName);

            ViewEngineResult result = null;
            IEnumerable<string> originalLocations = null;
            if (!isNullOrEmptyViewName)
            {
                // If view name was passed in is already a path, the view engine will handle this.
                result = viewEngine.GetView(viewContext.ExecutingFilePath, ViewName, isMainPage: false);
                originalLocations = result.SearchedLocations;
            }

            if (result == null || !result.Success)
            {
                // This will produce a string like:
                //
                //  Components/Cart/Default
                //
                // The view engine will combine this with other path info to search paths like:
                //
                //  Views/Shared/Components/Cart/Default.cshtml
                //  Views/Home/Components/Cart/Default.cshtml
                //  Areas/Blog/Views/Shared/Components/Cart/Default.cshtml
                //
                // This supports a controller or area providing an override for component views.
                var viewName = isNullOrEmptyViewName ? DefaultViewName : ViewName;
                var qualifiedViewName = string.Format(
                    CultureInfo.InvariantCulture,
                    ViewPathFormat,
                    context.ViewComponentDescriptor.ShortName,
                    viewName);

                result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
            }

            var view = result.EnsureSuccessful(originalLocations).View;
            using (view as IDisposable)
            {
                if (_diagnosticSource == null)
                {
                    _diagnosticSource = viewContext.HttpContext.RequestServices.GetRequiredService<DiagnosticSource>();
                }

                _diagnosticSource.ViewComponentBeforeViewExecute(context, view);

                var childViewContext = new ViewContext(
                    viewContext,
                    view,
                    ViewData ?? context.ViewData,
                    context.Writer);
                await view.RenderAsync(childViewContext);

                _diagnosticSource.ViewComponentAfterViewExecute(context, view);
            }
        }