通过代码生成机制实现强类型编程-CodeSimth版

本文介绍如何使用CodeSimth生成C#代码,并提供一个具体示例,展示了从XML配置文件读取数据并生成相应的类和静态成员的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        一直想写一个Code生成系列,但写到CodeSimth,发觉在TerryLee努力学习的小熊 两位大牛的博客里讲很详尽,所以就像写些示例方面的,但是苦于没有想到写些什么。最近Artech写了两篇从数据到代码——通过代码生成机制实现强类型编程--上篇和下篇,大牛写得是CodeDom的,今天我就想借借大牛的示例写个CodeSimth版的,希望Artech不要怪我,呵呵。我的Code生成技术已经写了CodeDom的见CodeDom系列目录,欢迎各位园友指教。

        好直接到主题。首先是数据实体MessageEntry(我到老A的基础上添加了description属性作为代码字段描述):

namespace Wolf
{
    public class MessageEntry
    {
        public string Id { get; private set; }
        public string Value { get; private set; }       
        public string Description { get; private set; }
        public MessageEntry(string id, string value)
        {
            this.Id = id;
            this.Value = value;        
        }

        public MessageEntry(string id, string value, string description)
        {
            this.Id = id;
            this.Value = value;
            this.Description = description;
        }

        public string Format(params object[] args)
        {
            return string.Format(this.Value, args);
        }
    }
}

在我的机子上的COdeSimth是2..0版本的所以不能使用Linq命名空间,我又想利用这个空间,比较快捷,所以我就在先3.0转化为

Dictionary >实体再传入模板:

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace Wolf
{
    public class MessageCodeGenerator
    {
        public Dictionary > GeneratorCode(string  path)
        {
            return GeneratorCode(XElement.Load(path));
        }
        public Dictionary > GeneratorCode(XElement root)
        {

            var elemts = root.Elements("message").GroupBy(e => ((XAttribute)e.Attribute("category")).Value);
            Dictionary > dict = new Dictionary >();
            foreach (var item in elemts)
            {
                List list = new List ();
                foreach (var g in item)
                {
                    if (g.Attribute("description") != null)
                    {
                        list.Add(new MessageEntry(((XAttribute)g.Attribute("id")).Value, ((XAttribute)g.Attribute("value")).Value, ((XAttribute)g.Attribute("description")).Value));
                    }
                    else
                    {
                        list.Add(new MessageEntry(((XAttribute)g.Attribute("id")).Value, ((XAttribute)g.Attribute("value")).Value));
                    }

                }
                dict.Add(item.Key.ToString(), list);
            }
            return dict;

        }
    }
}

这下几可开始写模板了,见下Code:

<%@ CodeTemplate Language="C#" TargetLanguage="Text" Src="" Inherits="" Debug="False" Description="Template description here." %>

<%@ Import NameSpace="System" %>
<%@ Import NameSpace="System.Xml" %>
<%@ Import NameSpace="System.Text" %>
<%@ Import NameSpace="System.Collections.Generic" %>
<%@ Import NameSpace="Wolf" %>
<%@ Assembly Name="Wolf" %>


//Copyright (C) Wolf.  All rights reserved.
<%=  GeneratorCode()%>

很简单,就不说了,如果有问题请留言,其中命名空间完全可以以属性方式传入。

XMl实体用的是老A的:

 
  
  
  
 

我想脱离CodeSimth工具,所以在建立了一个控制台程序,引用CodeSmith.Engine.dll程序集。

Code:

static void Main(string[] args)
       {
          // Wolf.Message.Messages.Confirmation.ReallyDelete.Value
           // test();
           CodeTemplate template = CompileTemplate(@"E:/MyApp/LinqTest/ConsoleApplication1/MessageCodeGenerator.cst",s=>Console.WriteLine(s));
           if (template != null)
           {
               template.SetProperty("_MessageFilePath", "");
               Wolf.MessageCodeGenerator gen = new MessageCodeGenerator();
               Dictionary > dict = gen.GeneratorCode(@"E:/MyApp/LinqTest/ConsoleApplication1/Sample.xml");
               template.SetProperty("Generator", dict);
               template.RenderToFile("gen.cs", true);
              // System.Diagnostics.Process.Start("gen.cs");
           }
          // Console.Read();

       }

       public static CodeTemplate CompileTemplate(string templateName,Action errorWriter)
       {
           CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateName);
           compiler.Compile();

           if (compiler.Errors.Count == 0)
           {
               return compiler.CreateInstance();
           }
           else
           {
               for (int i = 0; i < compiler.Errors.Count; i++)
               {
                   errorWriter(compiler.Errors[i].ToString());
               }
               return null;
           }

       }

生成后的代码:

//Copyright (C) Wolf.  All rights reserved.
using Wolf;
using System;
using System.Collections.Generic;
namespace Wolf.Message
{
    public class Messages
    {
        public class Validation
        {

            ///


            ///description
            ///

            public static Wolf.MessageEntry MandatoryField = new MessageEntry("MandatoryField",

"The {0} is mandatory.", "The {0} is mandatory.");

            ///


            ///description
            ///

            public static Wolf.MessageEntry GreaterThan = new MessageEntry("GreaterThan",

"The {0} must be greater than {1}.", "The {0} must be greater than {1}.");

        }

        public class Confirmation
        {

            ///


            ///description
            ///

            public static Wolf.MessageEntry ReallyDelete = new MessageEntry("ReallyDelete",

"Do you really want to delete the {0}.", "Do you really want to delete the {0}.");

        }

    }
}

ok,全部完成。同时你也可以完全集成与VS中利用VSX Vs扩展,可以参考明年我18 的VSX系列

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值