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


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

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

    代码
     1 namespace Wolf 
     2 
     3     public class MessageEntry 
     4     { 
     5         public string Id { getprivate set; } 
     6         public string Value { getprivate set; }        
     7         public string Description { getprivate set; } 
     8         public MessageEntry(string id, string value) 
     9         { 
    10             this.Id = id; 
    11             this.Value = value;         
    12         } 
    13 
    14         public MessageEntry(string id, string value, string description) 
    15         { 
    16             this.Id = id; 
    17             this.Value = value; 
    18             this.Description = description; 
    19         } 
    20 
    21         public string Format(params object[] args) 
    22         { 
    23             return string.Format(this.Value, args); 
    24         } 
    25     } 
    26 }
    27 
    28 

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

    Dictionary<string, List<MessageEntry>>实体再传入模板:

    Code:

    代码
     1 using System; 
     2 using System.Collections.Generic; 
     3 using System.Linq; 
     4 using System.Text; 
     5 using System.Xml; 
     6 using System.Xml.Linq; 
     7 
     8 namespace Wolf 
     9 
    10     public class MessageCodeGenerator 
    11     { 
    12         public Dictionary<string, List<MessageEntry>> GeneratorCode(string  path) 
    13         { 
    14             return GeneratorCode(XElement.Load(path)); 
    15         } 
    16         public Dictionary<string, List<MessageEntry>> GeneratorCode(XElement root) 
    17         { 
    18 
    19             var elemts = root.Elements("message").GroupBy(e => ((XAttribute)e.Attribute("category")).Value); 
    20             Dictionary<string, List<MessageEntry>> dict = new Dictionary<string, List<MessageEntry>>(); 
    21             foreach (var item in elemts) 
    22             { 
    23                 List<MessageEntry> list = new List<MessageEntry>(); 
    24                 foreach (var g in item) 
    25                 { 
    26                     if (g.Attribute("description"!= null
    27                     { 
    28                         list.Add(new MessageEntry(((XAttribute)g.Attribute("id")).Value, ((XAttribute)g.Attribute("value")).Value, ((XAttribute)g.Attribute("description")).Value)); 
    29                     } 
    30                     else 
    31                     { 
    32                         list.Add(new MessageEntry(((XAttribute)g.Attribute("id")).Value, ((XAttribute)g.Attribute("value")).Value)); 
    33                     } 
    34 
    35                 } 
    36                 dict.Add(item.Key.ToString(), list); 
    37             } 
    38             return dict; 
    39 
    40         } 
    41     } 
    42 }
    43 
    44 

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

    代码
     1 <%@ CodeTemplate Language="C#" TargetLanguage="Text" Src="" Inherits="" Debug="False" Description="Template description here." %> 
     2 
     3 <%@ Import NameSpace="System" %> 
     4 <%@ Import NameSpace="System.Xml" %> 
     5 <%@ Import NameSpace="System.Text" %> 
     6 <%@ Import NameSpace="System.Collections.Generic" %> 
     7 <%@ Import NameSpace="Wolf" %> 
     8 <%@ Assembly Name="Wolf" %> 
     9 
    10 <script runat="template"> 
    11 
    12 private Dictionary<string, List<MessageEntry>> dict; 
    13 public Dictionary<string, List<MessageEntry>> Generator 
    14 
    15     get 
    16     { 
    17         return dict; 
    18     } 
    19     set 
    20     { 
    21         dict=value; 
    22     } 
    23 
    24 
    25 public string GeneratorCode() 
    26         {            
    27             string str = "using Wolf;\r\nusing System;\r\nusing System.Collections.Generic;\r\nnamespace Wolf.Message\r\n{ \r\n   public class Messages\r\n    {\r\n"
    28             foreach (string catage in Generator.Keys) 
    29             { 
    30                 str += "        public class  "+catage + "\r\n        {        \r\n"
    31                 foreach (Wolf.MessageEntry entry in Generator[catage]) 
    32                 { 
    33                     str += "\r\n            /// <summary>" + 
    34                     "\r\n            ///" + entry.Description + 
    35                     "\r\n            /// </summary>" + 
    36                     "\r\n            public static Wolf.MessageEntry " + entry.Id + " = new MessageEntry(\"" + entry.Id + "\", \"" + entry.Value +"\", \"" + entry.Value +"\");\r\n"
    37                 } 
    38                 str += "\r\n        }\r\n\r\n"
    39 
    40             } 
    41             str += "\r\n    }\r\n}"
    42             return str; 
    43         } 
    44 
    45 </script> 
    46 //Copyright (C) Wolf.  All rights reserved. 
    47 <%=  GeneratorCode()%>
    48 
    49 

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

    XMl实体用的是老A的:

    代码
    1 <?xml version="1.0" encoding="utf-8" ?>  
    2 <messages>   
    3 <message id="MandatoryField" value="The {0} is mandatory."  category="Validation"  description="description" />   
    4 <message id="GreaterThan" value="The {0} must be greater than {1}."  category="Validation" description="description" />   
    5 <message id="ReallyDelete" value="Do you really want to delete the {0}."  category="Confirmation" description="description" />  
    6 </messages>
    7 
    8 

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

    Code:

    代码
     1 static void Main(string[] args) 
     2        { 
     3           // Wolf.Message.Messages.Confirmation.ReallyDelete.Value 
     4            // test(); 
     5            CodeTemplate template = CompileTemplate(@"E:\MyApp\LinqTest\ConsoleApplication1\MessageCodeGenerator.cst",s=>Console.WriteLine(s)); 
     6            if (template != null
     7            { 
     8                template.SetProperty("_MessageFilePath"""); 
     9                Wolf.MessageCodeGenerator gen = new MessageCodeGenerator(); 
    10                Dictionary<string, List<MessageEntry>> dict = gen.GeneratorCode(@"E:\MyApp\LinqTest\ConsoleApplication1\Sample.xml"); 
    11                template.SetProperty("Generator", dict); 
    12                template.RenderToFile("gen.cs"true); 
    13               // System.Diagnostics.Process.Start("gen.cs"); 
    14            } 
    15           // Console.Read(); 
    16 
    17        }
    18 
    19        public static CodeTemplate CompileTemplate(string templateName,Action<string> errorWriter) 
    20        { 
    21            CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateName); 
    22            compiler.Compile(); 
    23 
    24            if (compiler.Errors.Count == 0
    25            { 
    26                return compiler.CreateInstance(); 
    27            } 
    28            else 
    29            { 
    30                for (int i = 0; i < compiler.Errors.Count; i++
    31                { 
    32                    errorWriter(compiler.Errors[i].ToString()); 
    33                } 
    34                return null
    35            } 
    36 
    37        }
    38 
    39 

    生成后的代码:

    代码
     1 //Copyright (C) Wolf.  All rights reserved. 
     2 using Wolf; 
     3 using System; 
     4 using System.Collections.Generic; 
     5 namespace Wolf.Message 
     6 
     7     public class Messages 
     8     { 
     9         public class Validation 
    10         { 
    11 
    12             /// <summary> 
    13             ///description 
    14             /// </summary> 
    15             public static Wolf.MessageEntry MandatoryField = new MessageEntry("MandatoryField"
    16 
    17 "The {0} is mandatory.""The {0} is mandatory."); 
    18 
    19             /// <summary> 
    20             ///description 
    21             /// </summary> 
    22             public static Wolf.MessageEntry GreaterThan = new MessageEntry("GreaterThan"
    23 
    24 "The {0} must be greater than {1}.""The {0} must be greater than {1}."); 
    25 
    26         } 
    27 
    28         public class Confirmation 
    29         { 
    30 
    31             /// <summary> 
    32             ///description 
    33             /// </summary> 
    34             public static Wolf.MessageEntry ReallyDelete = new MessageEntry("ReallyDelete"
    35 
    36 "Do you really want to delete the {0}.""Do you really want to delete the {0}."); 
    37 
    38         } 
    39 
    40     } 
    41 }
    42 
    43 

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


    作者:破  狼
    出处:http://www.cnblogs.com/whitewolf/
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客博客园--破狼51CTO--破狼

  • 相关阅读:
    喜讯|恒生电子LightDB完成分布式数据产品稳定性测试
    PostgreSQL limit的ties子句
    实时通信 | pusher 如何使用私有频道(四)
    实时通信 | pusher 客户端事件(五)
    实时通信 | pusher 案例:实时图表(六)
    实时通信 | pusher 演示与频道实时通信(三)
    PHP系列 | MeiliSearch 轻量搜索引擎入门介绍
    实时通信 | pusher 频道介绍(二)
    实时通信 | pusher 入门教程(一)
    袁创:总结创业十年经验
  • 原文地址:https://www.cnblogs.com/whitewolf/p/CodeSimthNamedCMessage.html
Copyright © 2020-2023  润新知