[英]How can I use RazorGenerator instead of T4 for generating C# files?
我想使用http://razorgenerator.codeplex.com/代替Visual Studio的T4功能根據我的解決方案的代碼模型自動生成C#文件/類。 我已經在T4上使用EnvDTE成功完成了此操作,但是,我想使用比T4更可維護和更好支持的功能。
我嘗試通過@* Generator: Template *@
使用Template生成@* Generator: Template *@
,但是從中得到的輸出是帶有Execute
函數的C#類,該函數將生成我需要的模板化c#類。 如何將C#輸出直接輸入到解決方案中?
在解決方案中選擇cshtml文件,打開屬性窗格(默認為F4),然后輸入“ RazorGenerator”(不帶引號)作為自定義工具。 當您構建項目時,這將生成一個C#源文件。
編輯-實際也執行生成的類
這更加困難,並且您可能找不到像RazorGenerator這樣的預制自定義工具來為您完成此任務。 我將看一下RazorGenerator的源代碼,以了解他們如何構建自定義工具/擴展方面。 我可能甚至可以擴展RazorGenerator代碼並對其進行修改以滿足我的需要。
這是我用來從剃刀標記生成Type的方法。 這是MVC特有的一些技巧,您可能會忽略(例如,添加代碼以添加引用的程序集,這樣編譯就不會失敗)。
private Type CompileRazorView(string virtualPath, FileInfo file, Assembly partialViewAssembly)
{
var config = WebConfigurationManager.OpenWebConfiguration("~/Views/web.config");
var section = config.GetSectionGroup("system.web.webPages.razor") as RazorWebSectionGroup;
var host = MvcWebRazorHostFactory.CreateHostFromConfig(section, virtualPath);
var engine = new RazorTemplateEngine(host);
using (var stream = file.OpenRead())
{
using (var reader = new StreamReader(stream))
{
var result = engine.GenerateCode(reader);
string code = null;
using (var tw = new StringWriter())
{
CodeProvider.GenerateCodeFromCompileUnit(result.GeneratedCode, tw, new CodeGeneratorOptions());
tw.Flush();
code = tw.ToString();
}
var compilerParameters = new CompilerParameters()
{
MainClass = host.DefaultClassName,
GenerateInMemory = true,
IncludeDebugInformation = true,
};
var thisAssembly = Application.GetType().Assembly;
var thisAssemblyName = thisAssembly.GetName();
var referencedAssemblies = new List<AssemblyName>();
referencedAssemblies.Add(thisAssemblyName);
referencedAssemblies.Add(partialViewAssembly.GetName());
referencedAssemblies.AddRange(partialViewAssembly.GetReferencedAssemblies());
foreach (var applicationReference in thisAssembly.GetReferencedAssemblies())
{
var assembly = Assembly.Load(applicationReference.FullName);
referencedAssemblies.Add(assembly.GetName());
referencedAssemblies.AddRange(assembly.GetReferencedAssemblies());
}
var binPath = Path.GetDirectoryName(thisAssemblyName.CodeBase);
var distinctReferences = referencedAssemblies.Distinct((a, b) =>
string.Equals(a.FullName, b.FullName, StringComparison.OrdinalIgnoreCase)).ToList();
foreach (var reference in distinctReferences)
{
var referencedAssembly = Assembly.Load(reference.FullName).CodeBase.Substring("file:///".Length);
compilerParameters.ReferencedAssemblies.Add(referencedAssembly);
}
var compilerResults = CodeProvider.CompileAssemblyFromDom(compilerParameters, result.GeneratedCode);
if (compilerResults.Errors.HasErrors)
{
var errorText = new StringBuilder();
foreach (var compilerError in compilerResults.Errors)
{
errorText.AppendLine(compilerError.ToString());
}
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
"The following errors were detected attempting to compile the partial view {0}: \n{1}",
virtualPath, errorText));
}
var typeName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}",
host.DefaultNamespace, host.DefaultClassName);
var type = compilerResults.CompiledAssembly.GetType(typeName);
return type;
}
}
}
此方法將為您提供一個Type,您可以將其與反射一起使用,以實現Execute方法,然后可以調用該方法。 訣竅將是改變WriteLiteral的含義,以使其輸出到任意流,例如cs文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.