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


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

    背景

     

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

     

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

     

    因为我觉得动态编译很有意思,结合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。

     

    备注

     

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

     

  • 相关阅读:
    序号正确
    基于visual Studio2013解决C语言竞赛题之1071打印工资
    基于visual Studio2013解决C语言竞赛题之1070删除相同节点
    基于visual Studio2013解决C语言竞赛题之1069链表查找删除
    基于visual Studio2013解决C语言竞赛题之1068指针数组
    基于visual Studio2013解决C语言竞赛题之1067间隔排序
    基于visual Studio2013解决C语言竞赛题之1066进制转化
    基于visual Studio2013解决C语言竞赛题之1065二维排序
    基于visual Studio2013解决C语言竞赛题之1064互质数差1验证
    基于visual Studio2013解决C语言竞赛题之1063分橘子
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3070479.html
Copyright © 2020-2023  润新知