Skip to content

Instantly share code, notes, and snippets.

@LucGosso
Created November 26, 2021 10:01
Show Gist options
  • Save LucGosso/48544606987af8f4ec774b1b82a6fee2 to your computer and use it in GitHub Desktop.
Save LucGosso/48544606987af8f4ec774b1b82a6fee2 to your computer and use it in GitHub Desktop.
ViewEngine code example for featurefolders solutions .net5
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System;
using System.Linq;
using System.Reflection;
namespace Foundation.Infrastructure.Display
{
public class FeatureConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
controller.Properties.Add("feature", GetFeatureName(controller.ControllerType));
controller.Properties.Add("childFeature", GetChildFeatureName(controller.ControllerType));
}
private string GetFeatureName(TypeInfo controllerType)
{
string[] tokens = controllerType.FullName.Split('.');
if (!tokens.Any(t => t == "Features")) return "";
return tokens
.SkipWhile(t => !t.Equals("features",
StringComparison.CurrentCultureIgnoreCase))
.Skip(1)
.Take(1)
.FirstOrDefault();
}
private string GetChildFeatureName(TypeInfo controllerType)
{
var tokens = controllerType.FullName?.Split('.');
if (!tokens?.Any(t => t == "Features") ?? true)
{
return "";
}
return tokens
.SkipWhile(t => !t.Equals("features",
StringComparison.CurrentCultureIgnoreCase))
.Skip(2)
.Take(1)
.FirstOrDefault();
}
}
}
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Razor;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Site.Mvc.Business.Rendering
{
public class FeatureViewLocationExpander : IViewLocationExpander
{
private const string ChildFeature = "childfeature";
private const string Feature = "feature";
private readonly List<string> _viewLocationFormats = new List<string>()
{
"/Features/Shared/{0}.cshtml",
"/Features/Blocks/{0}.cshtml",
"/Features/Blocks/{1}/{0}.cshtml",
"/Features/Shared/Views/{0}.cshtml",
"/Features/Shared/Views/{1}/{0}.cshtml",
"/Features/Shared/Views/Header/{0}.cshtml",
"/Cms/Views/{1}/{0}.cshtml",
"/Features/{3}/{1}{0}.cshtml",
"/Features/{3}/{0}.cshtml",
"/Features/{3}/{4}/{1}/{0}.cshtml",
"/Features/{3}/{4}/{0}.cshtml",
"/FormsViews/Views/ElementBlocks/{0}.cshtml"
};
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
IEnumerable<string> viewLocations)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (viewLocations == null)
{
throw new ArgumentNullException(nameof(viewLocations));
}
var controllerActionDescriptor = context.ActionContext.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null && controllerActionDescriptor.Properties.ContainsKey("feature"))
{
string featureName = controllerActionDescriptor.Properties[Feature] as string;
string childFeatureName = null;
if (controllerActionDescriptor.Properties.ContainsKey(ChildFeature))
{
childFeatureName = controllerActionDescriptor.Properties[ChildFeature] as string;
}
foreach (var item in ExpandViewLocations(_viewLocationFormats.Union(viewLocations), featureName, childFeatureName))
{
yield return item;
}
}
else
{
foreach (var location in viewLocations)
{
yield return location;
}
}
}
public void PopulateValues(ViewLocationExpanderContext context)
{
var controllerActionDescriptor = context.ActionContext?.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor == null || !controllerActionDescriptor.Properties.ContainsKey(Feature))
{
return;
}
context.Values[Feature] = controllerActionDescriptor?.Properties[Feature].ToString();
if (controllerActionDescriptor.Properties.ContainsKey(ChildFeature))
{
context.Values[ChildFeature] = controllerActionDescriptor?.Properties[ChildFeature].ToString();
}
}
private IEnumerable<string> ExpandViewLocations(IEnumerable<string> viewLocations,
string featureName,
string childFeatureName)
{
foreach (var location in viewLocations)
{
var updatedLocation = location.Replace("{3}", featureName);
if (location.Contains("{4}") && string.IsNullOrEmpty(childFeatureName))
{
continue;
}
else
{
updatedLocation = updatedLocation.Replace("{4}", childFeatureName);
}
yield return updatedLocation;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment