1、引入RazorEngine组件
2、编写模板管理类TemplateManager.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RazorEngine;
using RazorEngine.Configuration;
using RazorEngine.Templating;
namespace GhisCodeGenerator.Comm
{
/// <summary>
/// 模板管理器
/// </summary>
public static class TemplateManager
{
public static string TemplateRootPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Tpls");
public static Dictionary<string, string> TemplateDic = new Dictionary<string, string>();
public static void Init()
{
//生成tpl文件
//CsHtmlToTpl();
var templateServiceConfiguration = new TemplateServiceConfiguration();
//这里可以类引用解决器
templateServiceConfiguration.ReferenceResolver = new CustomReferenceResolver();
Engine.Razor = RazorEngineService.Create(templateServiceConfiguration);
}
/// <summary>
/// Cses the HTML to TPL.
/// </summary>
private static void CsHtmlToTpl()
{
var root = new DirectoryInfo(TemplateRootPath);
var fileInfos = root.GetFiles("*.cshtml").ToList();
foreach (var directory in root.GetDirectories())
{
fileInfos.AddRange(directory.GetFiles("*.cshtml"));
}
fileInfos.ForEach(x =>
{
File.Copy(x.FullName, x.FullName.Replace(".cshtml", ".tpl"), true);
});
}
/// <summary>
/// Creates the directory and remove file.
/// </summary>
/// <param name="filepath">The filepath.</param>
public static void CreateDirectoryAndRemoveFile(string filepath)
{
var dir = Path.GetDirectoryName(filepath);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
if (File.Exists(filepath))
{
File.Delete(filepath);
}
}
/// <summary>
/// 获取所有模板
/// </summary>
public static List<string> GetTpls()
{
var root = new DirectoryInfo(TemplateRootPath);
var fileInfos = root.GetFiles("*.cshtml").ToList();
foreach (var directory in root.GetDirectories())
{
fileInfos.AddRange(directory.GetFiles("*.cshtml"));
}
List<string> tpls = new List<string>();
foreach (FileInfo fileInfo in fileInfos)
{
tpls.Add(fileInfo.FullName.Replace(TemplateRootPath, "").TrimStart('\\'));
}
return tpls;
}
/// <summary>
/// Loads the templates.
/// </summary>
/// <param name="clearCache">if set to <c>true</c> [clear cache].</param>
public static void LoadTemplates(bool clearCache = false)
{
if (clearCache)
{
TemplateDic.Clear();
}
LoadTemplates(new DirectoryInfo(TemplateRootPath));
}
/// <summary>
/// Loads the templates.
/// </summary>
/// <param name="directoryInfo">The directory information.</param>
private static void LoadTemplates(DirectoryInfo directoryInfo)
{
if (!directoryInfo.Exists)
{
return;
}
var fileInfos = directoryInfo.GetFiles("*.cshtml");
foreach (var fileInfo in fileInfos)
{
LoadTemplate(fileInfo.FullName.Replace(TemplateRootPath, ""));
}
foreach (var directory in directoryInfo.GetDirectories())
{
LoadTemplates(directory);
}
}
/// <summary>
/// 加载模板
/// </summary>
/// <param name="relativePath">The relative path.</param>
public static void LoadTemplate(string relativePath)
{
relativePath = relativePath.TrimStart('\\');
//打开并且读取模板
string template = File.ReadAllText(Path.Combine(TemplateRootPath, relativePath));
//添加模板
Engine.Razor.AddTemplate(relativePath, template);
//编译模板
Engine.Razor.Compile(relativePath, null);
if (!TemplateDic.ContainsKey(relativePath))
{
TemplateDic.Add(relativePath, "");
}
else
{
TemplateDic[relativePath] = "";
}
}
/// <summary>
/// 运行模板
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="templatePath">The template path.</param>
/// <param name="model">The model.</param>
/// <returns></returns>
public static string Run<T>(string templatePath, T model)
{
return Engine.Razor.Run(templatePath, null, model);
}
public static string Run<T>(int idx, T model)
{
return Engine.Razor.Run(TemplateDic.Keys.ToList()[idx], null, model);
}
}
}编写CustomReferenceResolver.cs
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RazorEngine.Compilation;
using RazorEngine.Compilation.ReferenceResolver;
namespace GhisCodeGenerator.Comm
{
public class CustomReferenceResolver : IReferenceResolver
{
/// <summary>
/// <see cref="CompilerServiceBase.DynamicTemplateNamespace"/>
/// </summary>
protected internal const string DynamicTemplateNamespace = "CompiledRazorTemplates.Dynamic";
/// <summary>
/// See <see cref="IReferenceResolver.GetReferences"/>
/// </summary>
/// <param name="context"></param>
/// <param name="includeAssemblies"></param>
/// <returns></returns>
public IEnumerable<CompilerReference> GetReferences(TypeContext context = null, IEnumerable<CompilerReference> includeAssemblies = null)
{
return CompilerServicesUtility
.GetLoadedAssemblies()
.Where(a => !a.IsDynamic && File.Exists(a.Location) && !a.Location.Contains(DynamicTemplateNamespace))
.GroupBy(a => a.GetName().Name).Select(grp => grp.First(y => y.GetName().Version == grp.Max(x => x.GetName().Version))) // only select distinct assemblies based on FullName to avoid loading duplicate assemblies
.Select(a => CompilerReference.From(a))
.Concat(includeAssemblies ?? Enumerable.Empty<CompilerReference>());
}
}
}3、准备模板文件demo.cshtml

文件为什么是cshtml?因为我想让我编写模板的时候,能语法高亮,能有智能提示,能和mvc开发绑定数据一样去开发
注意:需要将我们的模板文件(.cshtml)属性调整为内容,阻止编译,我们要像使用txt一样去使用他们

4、模板是否正确,是否能编译通过,需要我们初始化,不然后期生成代码的时候,会非常慢
所以需要在程序启动时候去初始化
using System;
using System.Windows.Forms;
using GhisCodeGenerator.Comm;
namespace GhisCodeGenerator
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
TemplateManager.Init();//这里
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Frm_Main());
}
}
}这样做,会导致我们的程序启动的时候,稍微慢了一点点,但是为了后期使用非常流畅,还是值得
到这里,我们的准备工作已经完成,接下来就是运用了
5、运用,即点击生成代码按钮之后该干的事情
List<string> tpls = TemplateManager.GetTpls();//得到所有模板
for (var i = 0; i < tpls.Count; i++)
{ //一次处理所有模板
var codeStr = TemplateManager.Run(tpls[i], ClassInfo);//将模板和razor绑定的数据传过去,这个classInfo就是渲染数据
var path = Path.Combine(savepath, ClassInfo.OutPutFileName);//根据回写的地址输出文件,这里决定了输出文件位置和后缀名
TemplateManager.CreateDirectoryAndRemoveFile(path);//创建文件夹
using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) //写入文件
{
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(codeStr);
}
}
}模板一般都是很多个,而且生成的代码需要存放在不同的文件夹,文件名称和后缀也不一样,所以我们把FileName放在模板中来赋值
最后生成的文件输出的位置和后缀名,完全取决于模板文件中的OutPutFileName变量
川公网安备 51010702003150号
留下您的脚步
最近评论