使用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);
        }

    }
}

附件下载

猜你喜欢

转载自blog.csdn.net/lw112190/article/details/113330820