C#内嵌Python架构实现
C#通过IronPython内嵌Python脚本,实现了对业务逻辑抽象及判断,适合在大量订单需要进行校验的场合使用。
比如,贷款时会对用户进行核查,核查过程可能存在多个节点,并且节点可能会随着政策而不断改变,每个节点就相当于一个脚本,通过脚本的出口关键字来确定流程分支走向。
大概业务流程图如下:
代码实现部分
1、C#代码
using IronPython.Hosting; using Microsoft.Scripting; using Microsoft.Scripting.Hosting; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace IronPython调用示例 { class Program { static void Main(string[] args) { string logPath = Path.Combine("logs", "log.txt"); if (File.Exists(logPath)) { File.Delete(logPath); } FileStream fileStream = new FileStream(logPath, FileMode.OpenOrCreate); //Console.WriteLine("------------------------以下是C#执行日志信息------------------------"); try { string pythonCodePath = Path.Combine("templates", "pythonCode.txt"); string sourceCodePath = Path.Combine("pys", "performer.py"); if (!File.Exists(pythonCodePath)) { throw new Exception("Python模板不存在!"); } if (!File.Exists(sourceCodePath)) { throw new Exception("Python源代码文件不存在!"); } string[] pythonCodeContent = File.ReadAllText(pythonCodePath).Split(new string[] { "\r\n" }, StringSplitOptions.None); string[] sourceCodeContent = File.ReadAllText(sourceCodePath).Split(new string[] { "\r\n" }, StringSplitOptions.None); if (sourceCodeContent == null || sourceCodeContent.Length == 0) { throw new Exception("Python代码不能为空!"); } List<string> strList = new List<string>(pythonCodeContent); foreach (var item in sourceCodeContent) { strList.Add(" " + item); } string codes = ""; foreach (var s in strList) { codes += s + Environment.NewLine; } ScriptEngine engine = Python.CreateEngine(); ScriptSource source = engine.CreateScriptSourceFromString(codes); ScriptScope scope = engine.CreateScope(); source.Execute(scope); dynamic performer = scope.GetVariable("performer"); dynamic per = performer("1005"); per.run(); var out_param = per.out_param; Console.WriteLine(per.out_param); Console.ReadKey(); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.ReadKey(); } finally { fileStream.Close(); fileStream.Dispose(); } } } }
2、Python代码,模板(pythonCode.txt)
#.coding=utf-8 import db_manager class performer(): def __init__(self,in_param): self.out_param = '' self.in_param = in_param def run(self):
3、节点脚本(performer.py)
import datetime def get_now_time(): self.out_param = str(datetime.datetime.now()) def get_user_count(): order_id = self.in_param sql = "select * from user_info where id = "+ order_id +"" querys = db_manager.sqlserver().execute_query(sql) if(len(querys) >= 5): self.out_param = '业务办理失败,此用户在全国范围内办理号码已经超过了5个!' else: self.out_param = '初审通过,已进入人工审核阶段!' get_now_time() get_user_count()
注意,此项目需要安装IronPython,并且把里面bin目录复制到我们C# debug目录下,项目源代码:https://github.com/lishuyiba/PythonPerformer