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 + 动态编译的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did45769