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://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于NET:工作流中如何动态解析路由规则 之 T4 + 动态编译的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did45769