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

 

posted @ 2019-11-20 11:34  李树逸  阅读(2268)  评论(0编辑  收藏  举报