DIY--记一次改造NHibernate模板的经历--预备基础知识

   最近一直在学习NHibernate和Spring.NET这两个开源框架的文章,主要看的是冬哥的博客,确实写的不错,非常适合俺这样初学的菜菜。加之自己刚刚做了一个使用了这两个框架的项目,当时由于是老师带着做,所以主要是负责模块功能的实现,而至于底层的配置,数据访问等等我都没有深究,不过看到冬哥的这一系列文章后,我下决定要好好研究一番,最好到最后可以利用这些框架重构一下以前的一些项目,看看解放生产力的效果。

  话不多说,为了使用NHibernate,那肯定要有一个自己的CS模板,我使用的CS4.1,但里面自带的NHibernate模板明显不符合需求,我也很纳闷这样不符合要求的模板怎么会在CS中自带的模板中,因为NHibernate要求实体类的属性必须使用virtual进行修饰,处处virtual的原因简单言之就是一句话:为了延迟加载。

  相关的原理可以在Davy Brion的博客里找到相应的说明,原文是:must-everything-be-virtual-with-nhibernate/

  介于俺这种懒人以前一般都是用内置的模板,所以也没有管实现的细节,不过在改造之前,我们还是有必要了解一些基础知识,今天要写起所以也就顺带再复习一下吧。

      这里主要参照了TerryLee的CodeSmith系列文章,现在边讲别总结吧:

      1、新建一个CodeSmith的模板,选择C# Template,随后模板会自动生成一些代码,解析如下:

      首先看到的是一些注释

       <%--

            Name:

            Author:

            Description:

       --%>

        这些注释是写在CodeSmith模板中用于说明的,在CodeSmith模板中的添加的注释主要有以下几种:
        CodeSmith:
             <%-- Comments --%>
        VB.NET:
             <%-- 'Comments --%>
        C#:
             <%-- // Comments --%>
             <%-- /* Comments */ --%>  

      但是这样的注释在运行模板时不会输出,所以如果想要让生成的文件中有注释信息,就需要使用C#的注释,即 // 或 /*...*/ 这样的形式,这样模板在生成时会才会将其输出。

       继续往下,我们看到的是一些模板的声明

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

      

       其中Language表示在开发编写模板时使用的语言;

             TargetLanguage:只是对模板代码的一个分类,说明模板要基于那种语言生成相应的代码,这里将Text改为C#;

             Description顾名思义就是模板的一些说明信息;

             Inherits:所有CodeSmith模板默认继承自CodeSmith.Engine.CodeTemplate这个类提供模板使用的一些基本功能,像ASP.NET页面的Page类,这些被继承的类的属性可以被修改,但是这些新的类也必须继承CodeSmith.Engine.CodeTemplate。CodeSmith也同样可以找到这个类,当然你要引入一个组件包含这个类;

              Src:在某些方面Src和继承Inherits比较相似,它们都允许你从其他的类包含一些功能进模板。这两个属性的区别是,Src可以让类与你的模板被动态编译,而Inherits仅允许你提供一个已经编译好的类或组件;

              Debug:可以确定是否在模板中可以包含调试符号。如果将这个属性设置为True,则可以使用System.Diagnostics.Debugger.Break()方法来设置断点;

              LinePragmas:设置为True,模板的错误将被指向到模板的源代码。设置为False,模板的错误将被指向到编译的源代码。

      再往下,可以大致猜出是一些属性的声明

      <%@ Property Default="SomeValue" Optional="True" Category="Strings" Description="This is a sample string property." %>

      <%@ Property Default="True" Optional="False" Category="Booleans" Description="This is a sample boolean property." %>

      其中Name表示模版使用的参数的名称;
           Type:参数类型可以是任何.NET有效的数据类型,例如简单的String类型或者是CodeSmith的SchemaExplorer.DatabaseSchema类型。注意,类型必须是基类库的类型,例如用String或者Int32代替string和int;

           Default:默认值;

           Category:用来说明这个属性在CodeSmith Explorer的属性面板中的分类;

           Description:在属性面板中对于这个属性的描述;

           Optional:设置这个属性是否是必须的,设置为True表明这个参数值可有可无,设置为False则这个参数必须有值;

           Editor:表明在属性面板中输入这个属性的值时使用何种GUI(图形界面编辑器)编辑器;

           EditorBase:编辑器使用的基本类型,如果没有被说明,UITypeEditor为默认编辑器。

     自带的NHibernate.cst模板中就有下面的代码:

     [Editor(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
     public string OutputDirectory
     {
            get {return _outputDirectory;}
            set {_outputDirectory= value;}
     }

     这样单击此属性时就可以弹出文件夹选择路径的对话框了。

  接着是组件的声明

  <%@ Assembly %>

  参数说明:

    Name:需要引用组件的名称,组建必须存在于Global Assembly Cache,与CodeSmith在同一路径下或与模版文件在同一路径下。

    Src:要包含文件的相对路径。

  <%@ Import Namespace="System.Data" %>相当于引入C#和VB中的引入命名空间。

  做完了准备工作后,就可以正式开始模板代码的编写了,自动生成的代码如下:

    My static content here.

    My dynamic content here: "<%= SampleStringProperty %>"

    Call a script method: <%= SampleMethod() %>

    <% if (SampleBooleanProperty) { %>

        My conditional content here.

    <% } %>

  在CodeSmith中<% %>之间的内容就是模板代码,就和.NET MVC类似,而<%= %>标签表示在模版中输出一个字符串,可以是自定义的变量或常量,也可以是之前声明的属性。如果标签多了怕晕的话最好看看这篇:CodeSmith中快捷键的使用 ,尤其是其中的Ctrl+Shift+V,确实省了不少神。

  最后一个部分是script模板

  <script runat="template">

    // My methods here.

    public string SampleMethod()

    {

           return "Method output.";

    }

  </script>

   这个标签内部可以放置许多变量,函数等帮助模板操作,CodeSmith的NHibernate.inc中有大量操作数据库表、字段等方法的例子,值得研究。。。

作者:Rocky翔
出处:http://www.cnblogs.com/RockyMyx/
本文版权归作者和博客园共有,欢迎转载,但请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2010-06-08 18:33  RockyXiang  阅读(539)  评论(0编辑  收藏  举报