<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Visual Studio DSL 入門 13---結(jié)合T4生成代碼

           在前面的幾節(jié)里,我們已經(jīng)完成了一個(gè)簡單的狀態(tài)機(jī)設(shè)計(jì)器,通過這個(gè)狀態(tài)機(jī)可以設(shè)計(jì)出一個(gè)狀態(tài)流,但是如果只是這樣,我們直接使用UML設(shè)計(jì)工具就行了,何必自己開發(fā)呢? 我們走的是模型驅(qū)動(dòng)開發(fā)路線,呵呵,注意哥說的是開發(fā),不是設(shè)計(jì).這一節(jié)就和我們的開發(fā)聯(lián)系起來,生成符合我們要求的代碼.
           結(jié)合vs.net dsl生成代碼有以下幾種方式:
           直接硬編碼,在代碼里面利用模型拼接生成的代碼,我記得activewriter就是這樣做的生成nhibernate代碼.
           結(jié)合模板引擎,你可以使用xslt或者t4(text template  transformation toolkit),或者是codesmith等.

           在這里我們使用T4來生成,vs.net已經(jīng)內(nèi)置支持T4引擎(dsl和linq等都是使用t4來生成的), 即使這樣,vs.net也沒有內(nèi)置對(duì)T4文件的編輯器,在開始下面之前,需要從這里下載免費(fèi)的Community版本安裝.
           1.直接運(yùn)行我們的項(xiàng)目,可以發(fā)現(xiàn)在Debugging項(xiàng)目下面有兩個(gè)tt文件,這兩個(gè)文件就是生成簡單代碼的一個(gè)例子,直接打開LanguageSmReport.tt

      隱藏行號(hào) 復(fù)制代碼
      1. <#@Import Namespace="System" #>
      2. <#@template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" language="C#" #>
      3. <#@output extension=".txt" #>
      4. <#@ LanguageSm processor="LanguageSmDirectiveProcessor" requires="fileName='Test.mydsl5'" #>
      5. 
        
      6. <#
      7. foreach (State state in StateMachine.States) {
      8. #>
      9. <#=state.Name #>
      10. <#
      11.       }
      12. #>

          2.運(yùn)行自定義工具,生成的文件就是附屬的txt文件:

      隱藏行號(hào) 復(fù)制代碼
      1.     Draft
      2.     NewOrder
      3.     Cancelled
      4.     Confirmed

         3. 對(duì)應(yīng)的我們的狀態(tài)機(jī)是我建立的一個(gè)簡單的訂單狀態(tài)流轉(zhuǎn):
       2010-3-12 23-10-41

            4.回頭過來再看一下這個(gè)t4模板文件,看起來其實(shí)很象aspx頁面:
             (1).通過Import引用需要的命名空間,事先所在的dll一定要添加到項(xiàng)目中.
             (2).第二行指定模板繼承自Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation,指定模板語言使用C#,注意,如果你需要使用framework 3.5,這里需要設(shè)置成C#3.5.
             (3).通過output指令設(shè)置生成文件的后綴名和編碼.
             (4).聲明我們的指令處理器以及需要加載的模型文件.
       
             (5).模板的正文很容易理解,只需要記住它的幾個(gè)控制塊的類型.
                <#….#>標(biāo)準(zhǔn)控制塊,里面放控制語句,就是我們普通的C#或者VB代碼組成的控制語句.
                <#+..#>類特性控制塊,里面可以添加方法,屬性,域或者內(nèi)嵌類,在這里一般放一些重用性高的代碼.
                <#=…#>表達(dá)式控制塊,計(jì)算里面包含的表達(dá)式的值并輸出.

           5.但是這個(gè)T4文件又是怎么樣的運(yùn)行解析機(jī)制呢,其實(shí)它和我們的aspx頁面很類似,我們來看一下它生成的轉(zhuǎn)換類:

      隱藏行號(hào) 復(fù)制代碼
      1. public class GeneratedTextTransformation : Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation {
      2. 
        
      3. public override string TransformText() {
      4. try {
      5. this.Write("\r\n");
      6. this.Write("\r\n");
      7. this.Write("\r\n");
      8. this.Write("\r\n\r\n");
      9. 
        
      10. foreach (State state in StateMachine.States) {
      11. 
        
      12. this.Write("\r\n\t");
      13. this.Write(Microsoft.VisualStudio.TextTemplating.ToStringHelper.ToStringWithCulture(
      14.                           state.Name
      15.                     ));
      16. this.Write("\r\n");
      17. 
        
      18.                 }
      19. 
        
      20. this.Write("\r\n");
      21.             } catch (System.Exception e) {
      22.                 System.CodeDom.Compiler.CompilerError error = new System.CodeDom.Compiler.CompilerError();
      23.                 error.ErrorText = e.ToString();
      24.                 error.FileName = "template2.t4";
      25. this.Errors.Add(error);
      26.             }
      27. return this.GenerationEnvironment.ToString();
      28.         }
      29. 
        
      30. 
        
      31. private Company.LanguageSm.StateMachine statemachineValue;
      32. 
        
      33. private Company.LanguageSm.StateMachine StateMachine {
      34. get {
      35. return this.statemachineValue;
      36.             }
      37.         }
      38. protected override void Initialize() {
      39. this.AddDomainModel(typeof(Microsoft.VisualStudio.Modeling.Diagrams.CoreDesignSurfaceDomainModel));
      40. this.AddDomainModel(typeof(Company.LanguageSm.LanguageSmDomainModel));
      41. 
        
      42. 
        
      43. base.Initialize();
      44. if ((this.Errors.HasErrors == false)) {
      45.                 Microsoft.VisualStudio.Modeling.Transaction statemachineTransaction = null;
      46. try {
      47.                     Microsoft.VisualStudio.Modeling.SerializationResult serializationResult = new Microsoft.VisualStudio.Modeling.SerializationResult();
      48.                     statemachineTransaction = this.Store.TransactionManager.BeginTransaction("Load", true);
      49. this.statemachineValue = Company.LanguageSm.LanguageSmSerializationHelper.Instance.LoadModel(serializationResult, this.Store, "Test.mydsl5", null, null);
      50. if (serializationResult.Failed) {
      51. throw new Microsoft.VisualStudio.Modeling.SerializationException(serializationResult);
      52.                     }
      53.                     statemachineTransaction.Commit();
      54.                 } finally {
      55. if ((statemachineTransaction != null)) {
      56.                         statemachineTransaction.Dispose();
      57.                     }
      58.                 }
      59. 
        
      60. 
        
      61.             }
      62.         }
      63.     }

           通過Write方法輸出我的內(nèi)容,然后其實(shí)是對(duì)于我們的模型的根域類屬性,并重寫Initialize()方法進(jìn)行了初始化.
              6.回過頭來,我們要根據(jù)上面3中的訂單狀態(tài)圖,生成我們的代碼,最重要也是最基本的一點(diǎn),在你打算用T4生成代碼時(shí),你一定要對(duì)你想生成的代碼了如指掌.如果你連自己要什么都不知道,更不可能達(dá)到了. 我們以最基本的一個(gè)例子,雖然這樣寫代碼可能并不合理,不過在這里我們?yōu)榱耸箚栴}盡量簡單化:        

      隱藏行號(hào) 復(fù)制代碼
      1. /// <summary>
      2.       /// 訂單狀態(tài)
      3. /// </summary>
      4. public  enum OrderStateEnum
      5. {
      6.         Draft,
      7.         NewOrder,
      8.         Cancelled,
      9.         Confirmed,
      10.         }
      11. 
        
      12. 
        
      13. /// <summary>
      14.       /// 訂單生成
      15. /// </summary>
      16. public  partial  class Order
      17. {
      18. public OrderStateEnum  OrderState
      19.          {
      20. get;
      21. set;
      22.          }
      23. 
        
      24. public Order()
      25.         {
      26. 
        
      27.         }
      28. 
        
      29. protected  void    SaveOrder(Order order)
      30.         {    
      31. 
        
      32. if(order.OrderState ==  OrderStateEnum.Draft)
      33.                         order.OrderState =  OrderStateEnum.NewOrder;
      34. 
        
      35.         }
      36.       }

                  (1).我們需要為我們的所有的狀態(tài)生成到我們的枚舉類型OrderStateEnum中(狀態(tài)名就是枚舉名,值不考慮).
                  (2).在我們的Order類中,有一個(gè)固定的OrderStateEnum類型的屬性O(shè)rderState,表示當(dāng)前訂單的狀態(tài). 
                  (3).需要為我們的每一個(gè)轉(zhuǎn)移Transigion生成一個(gè)方法到我們的Order類中,方法名就是Transition的Event的值,方法體就是當(dāng)訂單的狀態(tài)為Transigion的發(fā)起者Predecessor時(shí),將訂單的狀態(tài)置為目標(biāo)Successor.也就是說在SaveOrder內(nèi),判斷如果訂單的狀態(tài)是Draft時(shí),就把訂單的狀態(tài)置為NewOrder.
            7.在明白了目標(biāo)代碼后,我們來寫我們的T4文件,首先需要添加一個(gè)公共的方法來獲取StateMachine里的所有的Transition.我們使用<#+#>來完成這個(gè)方法,注意這個(gè)方法需要放在整個(gè)模板文件的最下面.

      隱藏行號(hào) 復(fù)制代碼
      1. <#+
      2. System.Collections.Generic.IEnumerable<Transition> GetAllTransitions() {
      3. foreach (State s in StateMachine.States)
      4. foreach (Transition t in Transition.GetLinksToSuccessors(s))
      5. yield return t;
      6.        }
      7. #>

             8.剩下的工作就更簡單了,我們只需要遍歷這些Transition,對(duì)于每個(gè)Transition,對(duì)于它的Predessor和Successor進(jìn)行如上所說的判斷和賦值即可,而對(duì)于固定的部分,我們只需要以文本的形式寫出來就可以了:

      隱藏行號(hào) 復(fù)制代碼
      1.       /// <summary>
      2.       /// 訂單狀態(tài)
      3.       /// </summary>
      4.        public  enum OrderStateEnum
      5.         {
      6. <#
      7. PushIndent("    ");
      8. foreach (State state in StateMachine.States)
      9. WriteLine("    {0},", state.Name);
      10. PopIndent();
      11. #>
      12.         }
      13.       /// <summary>
      14.       /// 訂單生成
      15.       /// </summary>
      16.       public  partial  class Order
      17.       {
      18.          public OrderStateEnum  OrderState
      19.          {
      20.            get;
      21.            set;
      22.          }
      23. 
        
      24.         public Order()
      25.         {
      26. 
        
      27.         }
      28. 
        
      29.         public   void Save(Order order){
      30.             // to save order
      31.         }
      32. 
        
      33. <#
      34. foreach (Transition transition in GetAllTransitions()) {
      35. #>
      36. 
        
      37.         protected  void    <#=transition.Event#>
      38.         {    
      39. 
        
      40.              if(order.OrderState ==  OrderStateEnum.<#=transition.Predecessor.Name#>)
      41.                         order.OrderState =  OrderStateEnum.<#=transition.Successor.Name#>;
      42.            Save(order);
      43.         }
      44. <#
      45.               } 
      46. #>
      47.     }

             9.轉(zhuǎn)換模板,就可以看到我們生成的代碼了,雖然在這個(gè)例子中并沒有顯現(xiàn)出T4的強(qiáng)大,不過對(duì)于復(fù)雜的規(guī)范性的系統(tǒng)來說,能夠通過Dsl進(jìn)行設(shè)計(jì),然后結(jié)合T4生成那些代碼還是能夠極大的提高生產(chǎn)率的.

      隱藏行號(hào) 復(fù)制代碼
      1. /// <summary>
      2.       /// 訂單狀態(tài)
      3. /// </summary>
      4. public  enum OrderStateEnum
      5. {
      6.         Draft,
      7.         NewOrder,
      8.         Cancelled,
      9.         Confirmed,
      10.         }
      11. /// <summary>
      12.       /// 訂單生成
      13. /// </summary>
      14. public  partial  class Order
      15. {
      16. public OrderStateEnum  OrderState
      17.          {
      18. get;
      19. set;
      20.          }
      21. 
        
      22. public Order()
      23.         {
      24. 
        
      25.         }
      26. 
        
      27. public   void Save(Order order){
      28. // to save order
      29. }
      30. 
        
      31. 
        
      32. protected  void    SaveOrder(Order order)
      33.         {    
      34. 
        
      35. if(order.OrderState ==  OrderStateEnum.Draft)
      36.                         order.OrderState =  OrderStateEnum.NewOrder;
      37.            Save(order);
      38.         }
      39. 
        
      40. protected  void    CancelOrder(Order order)
      41.         {    
      42. 
        
      43. if(order.OrderState ==  OrderStateEnum.NewOrder)
      44.                         order.OrderState =  OrderStateEnum.Cancelled;
      45.            Save(order);
      46.         }
      47. 
        
      48. protected  void    ConfirmOrder(Order  order)
      49.         {    
      50. 
        
      51. if(order.OrderState ==  OrderStateEnum.NewOrder)
      52.                         order.OrderState =  OrderStateEnum.Confirmed;
      53.            Save(order);
      54.         }
      55. 
        
      56.     }

            10.需要注意的是,結(jié)合dsl和t4也不可能使你的一個(gè)項(xiàng)目不用手寫代碼了,它只能是能夠生成你比較固定的代碼部分,能夠抽象出來的,目前t4還不能夠解決生成代碼中允許直接簽入自定義代碼,所以現(xiàn)在一般以文件為分隔,通過partial機(jī)制,由t4生成的cs文件中專門存儲(chǔ)這些抽象出來的可生成部分,而這部分是不允許修改的,因?yàn)樵谀阈薷耐昴P秃笙麓芜€會(huì)重新生成,而你需要擴(kuò)展的部分,都以partial類的機(jī)制在另外一個(gè)類中.

      代碼下載

       

      參考資源
            1. Visual Stuido DSL 工具特定領(lǐng)域開發(fā)指南
            2. DSL Tools Lab     http://code.msdn.microsoft.com/DSLToolsLab  系列教程  [本系列的入門案例的主要參考]

      作者:孤獨(dú)俠客似水流年
      出處:http://lonely7345.cnblogs.com/
      本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

      posted @ 2010-03-14 20:50  孤獨(dú)俠客  閱讀(3355)  評(píng)論(4)    收藏  舉報(bào)
      主站蜘蛛池模板: 人妻影音先锋啪啪av资源| 另类专区一区二区三区| 正在播放酒店约少妇高潮| 中文字幕无码专区一VA亚洲V专| 蜜臀av午夜精品福利| 国产午夜福利小视频合集| 人人妻人人妻人人片av | 国产精品视频白浆免费视频| 视频一区二区三区刚刚碰| 国产99在线 | 亚洲| 日韩av片无码一区二区不卡 | 国产精品天天看天天狠| 中文字幕天天躁日日躁狠狠躁免费| 天堂v亚洲国产v第一次| 国产热A欧美热A在线视频| 人妻中出无码中字在线| 亚洲乱色伦图片区小说 | 国产午夜影视大全免费观看| 久久成人伊人欧洲精品| 天堂中文8资源在线8| 乱码中文字幕| 国产成人精彩在线视频| 亚洲av无码专区在线亚| 精品人妻中文字幕在线| 无码人妻精品丰满熟妇区 | 亚洲av第一区二区三区| 男人的天堂av社区在线| 毛片亚洲AV无码精品国产午夜| 国产精品污双胞胎在线观看| 国产精品视频一区二区噜| 办公室强奷漂亮少妇视频| 亚洲av成人在线一区| 蜜臀午夜一区二区在线播放| 国产高清一区二区不卡| 日日碰狠狠添天天爽五月婷| 潮安县| 激情动态图亚洲区域激情| 欧美极品色午夜在线视频| 一边吃奶一边摸做爽视频| 青青狠狠噜天天噜日日噜| 国产老妇伦国产熟女老妇高清|