Я написал хакерское решение для нашей проблемы.Он взламывает razorgenerators viewengine и удаляет все соответствующие записи из имеющегося (частного только для чтения) словаря.
Код запускается при запуске приложения.
Обсуждение дешево, покажите мне код:
private static void HackRazorGeneratorToAllowViewOverriding()
{
// first we search for the PrecompiledMvcEngine
var razorGeneratorViewEngine = ViewEngines.Engines.ToList().FirstOrDefault(ve => ve.GetType().Name.Contains("PrecompiledMvcEngine"));
if (razorGeneratorViewEngine == null)
return;
// retrieve the dictionary where it keeps the mapping between a view path and the (view object) type to instantiate
var razorMappings = (IDictionary<string, Type>)ReflectionUtils.GetPrivateReadonly("_mappings", razorGeneratorViewEngine);
// retrieve a list of all our cshtml files in our 'concrete' web project
var files = Directory.GetFiles(Path.Combine(WebConfigSettings.RootPath, "Views"), "*.cshtml", SearchOption.AllDirectories);
// do some kungfu on those file paths so that they are in the same format as in the razor mapping dictionary
var concreteViewPaths = files.Select(fp => string.Format("~{0}", fp.Replace(WebConfigSettings.RootPath, "").Replace(@"\", "/"))).ToList();
// loop through each of the cshtml paths (of our 'concrete' project) and remove it from the razor mappings if it's there
concreteViewPaths.ForEach(vp =>
{
if (razorMappings.ContainsKey(vp))
razorMappings.Remove(vp);
});
}
WebConfigSettings.RootPath содержит путь на HD к корню нашего веб-приложения.
Это частьнашего статического класса ReflectionUtils:
/// <summary>
/// Get a field that is 'private readonly'.
/// </summary>
public static object GetPrivateReadonly(string readonlyPropName, object instance)
{
var field = instance.GetType().GetField(readonlyPropName, BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null)
throw new NullReferenceException(string.Format("private readonly field '{0}' not found in '{1}'", readonlyPropName, instance));
return field.GetValue(instance);
}
Это помогло.Мы в основном заставляем PrecompiledMvcEngine «забыть» любое представление, которое мы имеем в нашем конкретном проекте.