zoukankan      html  css  js  c++  java
  • 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。

     

    备注

     

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

     

  • 相关阅读:
    Maximum Flow Exhaustion of Paths Algorithm
    ubuntu下安装java环境
    visualbox使用(二)
    vxworks一个超级奇怪的错误(parse error before `char')
    February 4th, 2018 Week 6th Sunday
    February 3rd, 2018 Week 5th Saturday
    February 2nd, 2018 Week 5th Friday
    February 1st, 2018 Week 5th Thursday
    January 31st, 2018 Week 05th Wednesday
    January 30th, 2018 Week 05th Tuesday
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3070479.html
Copyright © 2011-2022 走看看