好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

NET:工作流中如何动态解析路由规则 之 T4 + 动态编译

NET:工作流中如何动态解析路由规则 之 T4 + 动态编译

NET:工作流中如何动态解析路由规则 之 T4 + 动态编译

背景

 

在 上篇文章 中我介绍了如何用动态语言解释器执行路由规则,有很多朋友都给出了他们的选项,如下:

  集成解释器(Iron、Javascript等)。 动态编译。 解析为Lamda表达式。 模板引擎。

 

因为我觉得动态编译很有意思,结合T4可能会更舒服,这篇文章就用这个思路重新实现一下如何解析路由规则。

 

思路

  T4 + 动态编译 = 无限可能

 

如何使用动态编译解析这条规则(“LeaveDays>=5 && LeaveType=='病假'”)呢?思路有很多种,我立马想到的的有两种,将Leave的属性解析为某个方法的本地变量或方法所有类型的成员变量,下面就是动态编译后的方法:

 

 1   public   bool   IsSatisfied(Leave entity)
  2   {
  3       var  LeaveDays =  entity.LeaveDays;
  4       var  LeaveType =  entity.LeaveType;
  5       return  LeaveDays>= 5  && LeaveType== "  病假  "  ;
  6  }

 

实现( 代码下载 )

 

CSharpDynamicSpecification.cs

 

  1   using   System;
   2   using   System.Collections.Generic;
   3   using   System.Linq;
   4   using   System.Text;
   5   using   System.Threading.Tasks;
   6  
  7   using   Microsoft.CSharp;
   8   using   System.CodeDom.Compiler;
   9  
 10   namespace   DynamicExpressionStudy
  11   {
  12       public   sealed   class  CSharpDynamicSpecification<T> : IDynamicSpecification<T>
 13       {
  14           private   string   _expression;
  15  
 16           public  CSharpDynamicSpecification( string   expression)
  17           {
  18              _expression =  expression;
  19           }
  20  
 21           public   bool   IsSatisfied(T entity)
  22           {
  23               var  dynamicInstance =  this  .CompileAndCreateInstance();
  24  
 25               var  result =  dynamicInstance
  26                   .GetType()
  27                  .GetMethod( "  IsSatisfied  "  )
  28                  .Invoke(dynamicInstance,  new   object  [] { entity });
  29  
 30               return  ( bool  )result;
  31           }
  32  
 33           private   object   CompileAndCreateInstance()
  34           {
  35              CodeDomProvider provider =  new   Microsoft.CSharp.CSharpCodeProvider();
  36  
 37              CompilerParameters cp =  new   CompilerParameters();
  38              cp.GenerateExecutable =  false  ;
  39              cp.GenerateInMemory =  true  ;
  40              cp.TreatWarningsAsErrors =  false  ;
  41              cp.ReferencedAssemblies.Add(Environment.CurrentDirectory +  "  \\DynamicExpressionStudy.exe  "  );
  42  
 43               var  templator =  new  DynamicSpecificationClassTemplate( typeof  (T), _expression);
  44               var  sourceCode =  templator.TransformText();
  45  
 46              CompilerResults cr =  provider.CompileAssemblyFromSource(cp, sourceCode);
  47  
 48               return  Activator.CreateInstance(cr.CompiledAssembly.GetType( "  DynamicExpressionStudy.  "  +  templator.TempClassName));
  49           }
  50       }
  51  }

 

Program.cs

 

  1   using   System;
   2   using   System.Collections.Generic;
   3   using   System.Linq;
   4   using   System.Text;
   5   using   System.Threading.Tasks;
   6  
  7   namespace   DynamicExpressionStudy
   8   {
   9       class   Program
  10       {
  11           static   void  Main( string  [] args)
  12           {
  13               var  leave =  new   Leave
  14               {
  15                  LeaveDays =  5  ,
  16                  LeaveType =  "  病假  " 
 17               };
  18  
 19               var  specification =  new  CSharpDynamicSpecification<Leave>( "  LeaveDays>=5 && LeaveType==\"病假\"  "  );
  20  
 21               var  result =  specification.IsSatisfied(leave);
  22  
 23               Console.WriteLine(result);
  24           }
  25       }
  26  
 27       public   class   Leave
  28       {
  29           public   int  LeaveDays {  get ;  set  ; }
  30  
 31           public   string  LeaveType {  get ;  set  ; }
  32       }
  33  }

 

运行结果为:true。

 

备注

 

这些解析路由规则的思路,可以用在其他任何需要动态计算的场合,如:薪酬公式、考核公式、考勤公式等。

 

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于NET:工作流中如何动态解析路由规则 之 T4 + 动态编译的详细内容...

  阅读:38次