-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Get component view via reflection + fix headings (#33)
* feat: Improved component views factory start * feat: Get component views via reflection * fix: Missing reference + tests
- Loading branch information
1 parent
01f60b9
commit 1e20b4c
Showing
7 changed files
with
107 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,75 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Reflection; | ||
|
||
namespace Dfe.PlanTech.Web.Helpers; | ||
|
||
public static class ComponentViewsFactory | ||
public class ComponentViewsFactory | ||
{ | ||
public static string GetViewForType(object model) => $"Components/{model.GetType().Name}"; | ||
} | ||
private const string GENERATED_VIEW_NAMESPACE = "AspNetCoreGeneratedDocument"; | ||
private const string SHARED_PATH = "Views_Shared"; | ||
|
||
private readonly Type[] _viewTypes; | ||
private readonly ILogger<ComponentViewsFactory> _logger; | ||
|
||
public ComponentViewsFactory(ILogger<ComponentViewsFactory> logger) | ||
{ | ||
_viewTypes = GetSharedViewTypes().ToArray(); | ||
_logger = logger; | ||
} | ||
|
||
/// <summary> | ||
/// Tries to find matching shared view for the passed model, based on the model's name | ||
/// </summary> | ||
/// <param name="model">The model for a view</param> | ||
/// <param name="viewPath">Found view path (if any matching view)</param> | ||
/// <returns>Whether a view was successfully found or not</returns> | ||
public bool TryGetViewForType(object model, out string? viewPath) | ||
{ | ||
var componentTypeName = model.GetType().Name; | ||
|
||
var matchingViewType = _viewTypes.FirstOrDefault(FileNameMatchesComponentTypeName(componentTypeName)); | ||
|
||
if (matchingViewType == null) | ||
{ | ||
_logger.LogWarning("Could not find matching view for {model}", model); | ||
viewPath = null; | ||
return false; | ||
} | ||
|
||
viewPath = GetFolderPathForType(matchingViewType); | ||
|
||
return true; | ||
} | ||
|
||
/// <summary> | ||
/// Gets file path to view from the Type name | ||
/// </summary> | ||
/// <remarks> | ||
/// Removes "Views_Shared_ from the name, then replaces all underscores with forward slashes | ||
/// </remarks> | ||
/// <param name="matchingViewType"></param> | ||
/// <returns>Folder path to the view for this type</returns> | ||
private static string GetFolderPathForType(Type matchingViewType) | ||
=> matchingViewType.Name!.Replace("Views_Shared_", "").Replace("_", "/"); | ||
|
||
/// <summary> | ||
/// Does the passed component type name match the type name? | ||
/// </summary> | ||
/// <param name="componentTypeName"></param> | ||
/// <returns></returns> | ||
private static Func<Type, bool> FileNameMatchesComponentTypeName(string componentTypeName) | ||
=> type => type.Name.EndsWith($"_{componentTypeName}"); | ||
|
||
/// <summary> | ||
/// Get all Types generated from Views that are in the "Shared" folder (or sub-folder) | ||
/// </summary> | ||
private static IEnumerable<Type> GetSharedViewTypes() => Assembly.GetExecutingAssembly() | ||
.GetTypes() | ||
.Where(IsSharedViewType); | ||
|
||
/// <summary> | ||
/// Is this type a View type, which is in the Shared folder path? | ||
/// </summary> | ||
/// <param name="type"></param> | ||
/// <returns></returns> | ||
private static bool IsSharedViewType(Type type) => type.Namespace == GENERATED_VIEW_NAMESPACE && type.Name.StartsWith(SHARED_PATH); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
@using Dfe.PlanTech.Web.Helpers; | ||
@using Dfe.PlanTech.Domain.Content.Enums; | ||
|
||
@model Dfe.PlanTech.Domain.Content.Models.Header; | ||
|
||
<header heading=@Model></header> | ||
<header model=@Model></header> |
8 changes: 5 additions & 3 deletions
8
src/Dfe.PlanTech.Web/Views/Shared/Components/PageComponentFactory.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
@using Dfe.PlanTech.Domain.Content.Models; | ||
@using Dfe.PlanTech.Domain.Content.Models.Buttons; | ||
@using Dfe.PlanTech.Web.Helpers; | ||
|
||
@inject ComponentViewsFactory ComponentViewsFactory; | ||
|
||
@model Dfe.PlanTech.Domain.Content.Models.ContentComponent; | ||
|
||
@{ | ||
await Html.RenderPartialAsync(ComponentViewsFactory.GetViewForType(Model), Model); | ||
if(ComponentViewsFactory.TryGetViewForType(Model, out string? path) && !string.IsNullOrEmpty(path)){ | ||
await Html.RenderPartialAsync(path, Model); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters