使用Razor模板动态生成代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Web.Razor;
using System.IO;
namespace lxw_Compiler_RazorEngine
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btnGenerate_Click(object sender, EventArgs e)
{
string TemplateString = txtTemplate.Text;
Type ModelType = typeof(SampleModel);
string TemplateName = "T" + Guid.NewGuid().ToString("N") + "Template";
CSharpCodeProvider CodePrivoder = new CSharpCodeProvider();
ICodeCompiler objICodeCompiler = CodePrivoder.CreateCompiler();
var @params = new CompilerParameters();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (assembly.ManifestModule.Name != "<In Memory Module>")
@params.ReferencedAssemblies.Add(assembly.Location);
}
@params.GenerateInMemory = true;
@params.IncludeDebugInformation = false;
@params.GenerateExecutable = false;
@params.CompilerOptions = "/target:library /optimize";
var host = new RazorEngineHost(new CSharpRazorCodeLanguage());
host.DefaultBaseClass = string.Format("lxw_Compiler_RazorEngine.RazorTemplateBase<{0}>", ModelType.FullName);
host.DefaultNamespace = "lxw_Compiler_RazorEngine";
host.DefaultClassName = TemplateName;
host.NamespaceImports.Add("System");
GeneratorResults razorResult = null;
using (TextReader reader = new StringReader(TemplateString))
{
razorResult = new RazorTemplateEngine(host).GenerateCode(reader);
}
var builder = new StringBuilder();
var codeProvider = new CSharpCodeProvider();
using (var writer = new StringWriter(builder))
{
codeProvider.GenerateCodeFromCompileUnit(razorResult.GeneratedCode, writer, new CodeGeneratorOptions());
}
var result = codeProvider.CompileAssemblyFromSource(@params, new[] { builder.ToString() });
if (result.Errors.HasErrors)
{
StringBuilder sbErrs = new StringBuilder(builder.ToString() + System.Environment.NewLine);
sbErrs.Append("-----------代码中存在语法错误!-----------" + System.Environment.NewLine);
foreach (CompilerError err in result.Errors)
{
sbErrs.AppendFormat("{0},{1}" + System.Environment.NewLine, err.ErrorNumber, err.ErrorText);
}
MessageBox.Show(sbErrs.ToString());
return;
}
SampleModel sampleModel = new SampleModel();
sampleModel.Prop1 = "lxw01";
sampleModel.Prop2 = "lxw02";
sampleModel.Prop3 = new List<string> { "lxw03-1", "lxw03-2", "lxw03-3" };
var template = (RazorTemplateBase<SampleModel>)result.CompiledAssembly.CreateInstance("lxw_Compiler_RazorEngine." + TemplateName);
template.Model = sampleModel;
template.Execute();
var output = template.Buffer.ToString();
template.Buffer.Clear();
txtResult.Text = output;
}
private void frmMain_Load(object sender, EventArgs e)
{
}
}
public class SampleModel
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public List<string> Prop3 { get; set; }
}
public abstract class RazorTemplateBase<T>
{
public T Model { get; set; }
public StringBuilder Buffer { get; set; }
protected RazorTemplateBase()
{
Buffer = new StringBuilder();
}
public abstract void Execute();
public virtual void Write(object value)
{
WriteLiteral(value);
}
public virtual void WriteLiteral(object value)
{
Buffer.Append(value);
}
}
}
使用Razor模板动态生成代码的更多相关文章
- 基于ABP做一个简单的系统——实战篇:4.基于富文本编辑器,Razor模板引擎生成内容并导出Word 填坑记录
起因 需求是这样的,有一种协议需要生成,协议的模板是可配置的,在生成过程中,模板中的内容可以根据约定的标记进行替换(就像mvc的razor模板一样).生成后的内容还需要导出成word或pdf. 常见的 ...
- Emit动态生成代码
Emit动态生成代码 引用:秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, // specify a new assembly name var assemblyName = new ...
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...
- 【转】- 使用T4模板批量生成代码
前言 之前在 “使用T4模板生成代码 - 初探” 文章简单的使用了T4模板的生成功能,但对于一个模板生成多个实例文件,如何实现这个方式呢?无意发现一个解决方案 “MultipleOutputHelpe ...
- 秒懂C#通过Emit动态生成代码
首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new AssemblyName("Kitty&qu ...
- [小tips]使用vscode,根据vue模板文件生成代码
本着苍蝇虽小也是肉的精神...... 目标: 我们希望每次新建.vue文件后,VSCODE能够根据配置,自动生成我们想要的内容. 方法: 打开VSCODE编辑器,依次选择"文件 -> ...
- T4模板批量生成代码
大家通过比对下,就应该知道怎么玩. T4代码 <#@ template debug="false" hostspecific="true" languag ...
- 使用T4模板动态生成邮件内容并储存到任意位置
一.基础概念介绍 T4模板是扩展名为 .tt 的文本文件. 他分为设计时模板 和运行时模板.主要区别在于在vs中右键点击文件,打开“属性”,在“自定义工具”一栏中的值分别如下: 设计时模板: Text ...
- T4模板批量生成代码文件
<#@ template debug="false" hostspecific="true" language="C#" #> ...
- 使用T4模板动态生成NPoco实体类
这是一个妥妥的NPoco类,这是我们在工作开发中,手动去写这个实体类,属实非常心累,字段少无所谓一次两次,数量多了,字段多了,就心态裂开
随机推荐
- 48.DRF版本控制
版本控制 版本控制是前后端分离开发一个非常重要的内容,比如说我们重要服务修改.升级等发生版本变化v1.v2.v3等,但是版本发生了变化比如 v1升级到了v2版本,v1版本还有业务在继续使用,相当于同时 ...
- Wireguard笔记(一) 节点安装配置和参数说明
目录 Wireguard笔记(一) 节点安装配置和参数说明 Wireguard笔记(二) 命令行操作 Wireguard笔记(三) lan-to-lan子网穿透和多网段并存 简介 虚拟子网软件,类似于 ...
- Java 23种设计模式的分类和使用场景
听说过GoF吧? GoF是设计模式的经典名著Design Patterns: Elements of Reusable Object-Oriented Software(中译本名为<设计模式-- ...
- Jsp+Servlet实现文件上传下载(三)--删除上传文件
接着上一篇讲: Jsp+Servlet实现文件上传下载(二)--文件列表展示点击打开链接 本章来实现一下删除已上传文件,同时优化了一下第一章中的代码. 废话少说,上代码 --------------- ...
- [BUUCTF][Web][极客大挑战 2019]Secret File 1
打开靶机对应的url 右键查看网页源代码,查看到一个访问路径 /Archive_room.php 构造url访问一下 http://3bfaebad-fdfa-4226-ae0a-551f0228be ...
- 分发函数singledispatch
import functools @functools.singledispatch() def myfunc(arg): print("default myfunc({!r})" ...
- docker部署fastdfs并在Django中集成
拉取Fastdfs镜像 docker pull delron/fastdfs 构建Tracker容器 是在Linux环境下,使用docker镜像构建tracker容器,用于启动跟踪服务器,起到调度的作 ...
- 【Azure 应用服务】如果发现当前使用的订阅无法在China North 3 区中创建App Service服务,如何来解决这个问题呢?
问题描述 在创建App Service服务时,突然发现无法选择China North 3区域,如何来解决这个问题呢? 问题解答 根据Azure中服务都需要在订阅中注册的原理,因为China North ...
- 【Azure 应用服务】App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢?
问题描述 App Service 的.NET Version选择为.NET6,是否可以同时支持运行ASP.NET V4.8的应用呢? 问题解答 答案是可以的,Azure App Service .NE ...
- Codeforces Round 916 (Div. 3)(A~E2)
A 统计一下每个字母的出现次数然后输出即可 #include <bits/stdc++.h> #define rep(i,a,b) for(register int i = (a); i ...