One of the nice feature of the .NetCore framework is its pluggability. This means you can completely replace the default view engine(s) with a custom one.
One of the reason for using a custom view engine is to change the default views location and sometimes you need to change the views location at run-time. To do this you can extend the default view engine(s) and then change the default views location variables at run-time.
Here is an example when the default Checkout Views are replaced with Partial Views loaded from a Payment Plugin
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.Razor;
using Nop.Core;
using Nop.Core.Data;
using Nop.Core.Infrastructure;
using Nop.Services.Plugins;
using Nop.Services.Configuration;
using Nop.Web.Framework.Themes;
namespace Nop.Plugin.Pluign.Name.ViewEngine
{
public class CustomViewEngine : IViewLocationExpander
{
public string storeTheme = "DefaultClean";
public void PopulateValues(ViewLocationExpanderContext context)
{
if (context.AreaName?.Equals("Admin") ?? false)
return;
var settingService = EngineContext.Current.Resolve<ISettingService>();
var storeContext = EngineContext.Current.Resolve<IStoreContext>();
storeTheme = settingService.GetSettingByKey("storeinformationsettings.defaultstoretheme", "DefaultClean", storeContext.CurrentStore.Id, true);
var themeContext = (IThemeContext)context.ActionContext.HttpContext.RequestServices.GetService(typeof(IThemeContext));
context.Values[storeTheme] = themeContext.WorkingThemeName;
}
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
//Confirm database is installed
if (DataSettingsManager.DatabaseIsInstalled)
{
var pluginService = EngineContext.Current.Resolve<IPluginService>();
var plugin = pluginService.GetPluginDescriptorBySystemName<IPlugin>("Plugin.Name", LoadPluginsMode.InstalledOnly);
if (plugin != null)
{
if (plugin.SystemName == "Plugin.Name")
{
if (context.AreaName == "Admin")
{
}
else
{
if (!context.Values.TryGetValue(storeTheme, out string theme))
return viewLocations;
if (context.ControllerName == "RealOnePageCheckout" && context.ViewName == "RealOnePageCheckout")
{
viewLocations = new[] { $"~/Plugins/Plugin.Name/Views/FrontView/RealOnePageCheckout.cshtml" }.Concat(viewLocations);
}
else if (context.ControllerName == "Checkout" && context.ViewName == "BillingAddress")
{
viewLocations = new[] { $"~/Plugins/Plugin.Name/Views/FrontView/BillingAddress.cshtml" }.Concat(viewLocations);
}
else if (context.ControllerName == "Checkout" && context.ViewName == "ShippingMethod")
{
viewLocations = new[] { $"~/Plugins/Plugin.Name/Views/FrontView/ShippingMethod.cshtml" }.Concat(viewLocations);
}
else if (context.ControllerName == "Checkout" && context.ViewName == "OpcShippingMethods")
{
viewLocations = new[] { $"~/Plugins/Plugin.Name/Views/FrontView/OpcShippingMethods.cshtml" }.Concat(viewLocations);
}
else if (context.ControllerName == "Checkout" && context.ViewName == "Completed")
{
viewLocations = new[] { $"~/Plugins/Plugin.Name/Views/FrontView/Completed.cshtml" }.Concat(viewLocations);
}
}
}
}
}
return viewLocations;
}
}
}