public Type SelectComponent([NotNull] string componentName) { var assemblies = _assemblyProvider.CandidateAssemblies; var types = assemblies.SelectMany(a => a.DefinedTypes); var components = types .Where(ViewComponentConventions.IsComponent) .Select(c => new { Name = ViewComponentConventions.GetComponentName(c), Type = c.AsType() }); var matching = components .Where(c => string.Equals(c.Name, componentName, StringComparison.OrdinalIgnoreCase)) .ToArray(); if (matching.Length == 0) { return(null); } else if (matching.Length == 1) { return(matching[0].Type); } else { var typeNames = string.Join(Environment.NewLine, matching.Select(t => t.Type.FullName)); throw new InvalidOperationException( Resources.FormatViewComponent_AmbiguousTypeMatch(componentName, typeNames)); } }
public void IsComponent(Type type, bool expected) { // Arrange & Act var result = ViewComponentConventions.IsComponent(type.GetTypeInfo()); // Assert Assert.Equal(expected, result); }
/// <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>"Default"</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([NotNull] ViewComponentContext context) { var viewEngine = ViewEngine ?? ResolveViewEngine(context); var viewData = ViewData ?? context.ViewContext.ViewData; string qualifiedViewName; if (ViewName != null && ViewName.Length > 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. qualifiedViewName = string.Format( CultureInfo.InvariantCulture, ViewPathFormat, ViewComponentConventions.GetComponentName(context.ComponentType), ViewName ?? "Default"); } var view = FindView(context.ViewContext, viewEngine, qualifiedViewName); var childViewContext = new ViewContext( context.ViewContext, view, ViewData ?? context.ViewContext.ViewData, context.Writer); using (view as IDisposable) { await view.RenderAsync(childViewContext); } }
private static ViewComponentCandidate CreateCandidate(TypeInfo typeInfo) { var candidate = new ViewComponentCandidate() { FullName = ViewComponentConventions.GetComponentFullName(typeInfo), ShortName = ViewComponentConventions.GetComponentName(typeInfo), Type = typeInfo.AsType(), }; Debug.Assert(!string.IsNullOrEmpty(candidate.FullName)); var separatorIndex = candidate.FullName.LastIndexOf("."); if (separatorIndex >= 0) { candidate.ShortName = candidate.FullName.Substring(separatorIndex + 1); } else { candidate.ShortName = candidate.FullName; } return(candidate); }
protected virtual bool IsViewComponentType([NotNull] TypeInfo typeInfo) { return(ViewComponentConventions.IsComponent(typeInfo)); }