using Microsoft.CSharp;
|
using System;
|
using System.CodeDom.Compiler;
|
using System.Collections.Generic;
|
using System.Reflection;
|
using System.Text;
|
using Newtonsoft.Json;
|
//using EPAModelNameSpace;
|
//using System.Security.AccessControl;
|
using System.IO;
|
using System.Linq;
|
using System.Data;
|
using Hydro.CommonBase;
|
//using System.Security.Cryptography.X509Certificates;
|
//using Hydro.ConfigModel;
|
|
namespace Hydro.CodeProvider
|
{
|
public class EvalResult
|
{
|
public EvalResult(object obj, List<MethodInfo> infos)
|
{
|
this.obj = obj;
|
this.infos = infos;
|
}
|
public object obj;
|
public List<MethodInfo> infos;
|
|
}
|
/// <summary>
|
/// 使用方法:
|
/// 示例化MyEval,传入代码片段,选择模板类型或传入自定义模板
|
/// </summary>
|
[Serializable]
|
public class Eval
|
{
|
int paramNum;
|
string tempCode=null;
|
List<string> refs = new List<string>();
|
List<string> usings = new List<string>();
|
string code;
|
object tmp;
|
public void SetTmp(object tmp)
|
{
|
this.tmp = tmp;
|
}
|
|
public void SetMethodInfo(List<MethodInfo> info)
|
{
|
this.mi=info[FunctionIndex];
|
}
|
int FunctionIndex = -1;
|
MethodInfo mi;
|
public bool isInit;
|
public string errString;
|
|
//static MyEval instance;
|
//static List<MethodInfo> mis=new List<MethodInfo>();
|
public static dynamic CompileTotalInstance(EvalTemplate me_temp)
|
{
|
|
var code= me_temp.Get_code();
|
var me = new Eval(code);
|
//me.tmp = me.getInstance();
|
if (!me.isInit)
|
{
|
return me.errString;
|
}
|
else
|
{
|
List<MethodInfo> mis = new List<MethodInfo>();
|
Type type = me.tmp.GetType();
|
for(int i=0;i< me_temp.Count;i++)
|
{
|
mis.Add(type.GetMethod($"TMethod{i}"));
|
}
|
return new EvalResult(me.tmp,mis);
|
|
}
|
}
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
/// <param name="CharpCode">自由编写;参数:List<double> paramArray,返回值:double;</param>
|
/// <param name="num">用来做函数可行性测试,可以不填</param>
|
public Eval(string CharpCode,int num,bool isCommon=false,EvalTemplate me_temp=null)
|
{
|
if (!isCommon)
|
{
|
this.tempCode = EvalTemplate.TempCode_function;
|
code = CharpCode;
|
paramNum = num;
|
tmp = getInstance();
|
if (tmp is string)
|
{
|
isInit = false;
|
errString = tmp.ToString();
|
return;
|
}
|
|
Type type = tmp.GetType();
|
mi = type.GetMethod("myMethod");
|
isInit = true;
|
}
|
else
|
{
|
FunctionIndex = me_temp.Count;
|
CharpCode = TreatHead(CharpCode);
|
me_temp.Add_code(CharpCode);
|
isInit = true;
|
}
|
|
}
|
|
private string TreatHead(string CharpCode)
|
{
|
foreach (var line0 in CharpCode.Split('\n'))
|
{
|
string line = line0.Trim();
|
if (line.ToLower().IndexOf("import") == 0)
|
{
|
string ass = line.ToLower().Replace("import", "").Trim().Trim(';');
|
this.defaultRefs.Add(GlobalPath.configPath + ass);
|
CharpCode = CharpCode.Substring(line0.Length);
|
}
|
else if (line.ToLower().IndexOf("using") == 0)
|
{
|
string ass = line;
|
this.usings.Add(ass);
|
CharpCode = CharpCode.Substring(line0.Length);
|
|
}
|
else
|
{
|
break;
|
}
|
}
|
|
return CharpCode;
|
}
|
|
public Eval(string code)
|
{
|
this.tempCode = null;
|
this.code = code;
|
//paramNum = num;
|
tmp = getInstance();
|
if (tmp is string)
|
{
|
isInit = false;
|
errString = tmp.ToString();
|
return;
|
}
|
isInit = true;
|
|
}
|
/// <summary>
|
/// 构造
|
/// </summary>
|
/// <param name="CharpCode">函数的代码段</param>
|
/// <param name="tempCode"></param>
|
public Eval(string CharpCode, string tempCode=null)
|
{
|
CharpCode = TreatHead(CharpCode);
|
this.tempCode = tempCode;
|
code = CharpCode;
|
//paramNum = num;
|
tmp = getInstance();
|
if (tmp is string)
|
{
|
isInit = false;
|
errString = tmp.ToString();
|
return;
|
}
|
|
Type type = tmp.GetType();
|
mi = type.GetMethod("myMethod");
|
isInit = true;
|
|
}
|
|
public List<string> defaultRefs = new List<string>()
|
{
|
"system.dll"
|
,"Microsoft.CSharp.dll"
|
,"System.Data.dll"
|
,"System.Windows.Forms.dll"
|
,"Microsoft.VisualBasic.dll"
|
,"System.Management.dll"
|
,"System.Drawing.dll"
|
|
,"System.Runtime.dll"
|
,"System.Collections.dll"
|
,"System.Linq.dll"
|
,GlobalPath.Path+ "Hydro.CommonBase.dll"
|
,GlobalPath.Path+ "Hydro.CodeProvider.dll"
|
//,Directory.GetCurrentDirectory()+"\\"+ "CommonBase.dll"
|
//,Directory.GetCurrentDirectory() + "\\" + "CodeProvider.dll"
|
// ,Directory.GetCurrentDirectory() + "\\" + "HydraulicModel.dll"
|
};
|
|
/// <summary>
|
/// 返回函数进行调用,调用方式resultMehodInfo.Invoke(tmp, null)
|
/// </summary>
|
/// <param name="CharpCode"></param>
|
/// <returns></returns>
|
private object getInstance()
|
{
|
var d = new Dictionary<string, string>() {
|
{ "CompilerVersion", "v4.0" },
|
};
|
CodeDomProvider csharpCodeProvider= CodeDomProvider.CreateProvider("CSharp", d);
|
ICodeCompiler compiler = csharpCodeProvider.CreateCompiler();
|
|
CompilerParameters cp = new CompilerParameters();
|
|
|
defaultRefs.ForEach(refs => cp.ReferencedAssemblies.Add(refs));
|
|
cp.CompilerOptions = $"/t:library /platform:anycpu /optimize+";
|
|
cp.GenerateInMemory = true;
|
|
|
StringBuilder sourceCode = new StringBuilder();
|
|
//return paramArray[0] + paramArray[1] * 3 + paramArray[2];
|
if (tempCode!=null)
|
{
|
sourceCode.Append(tempCode.Replace("{0}", code));
|
}
|
|
else
|
{
|
sourceCode.Append(code);
|
}
|
//myCode.Append("}\r\n");
|
|
CompilerResults cr = compiler.CompileAssemblyFromSource(cp, sourceCode.ToString());
|
if (cr.Errors.Count > 0)
|
{
|
string errString = "";
|
foreach(var err in cr.Errors)
|
{
|
errString += err.ToString()+"\r\n";
|
}
|
return $"//目标函数表达式编译失败\r\n//{errString}\r\n{sourceCode}";
|
}
|
|
Assembly assembly = cr.CompiledAssembly;
|
|
object tmp = assembly.CreateInstance("CoustomEval.myLib");
|
|
return tmp;
|
|
|
|
|
|
|
|
}
|
|
/// <summary>
|
/// 返回函数进行调用,调用方式resultMehodInfo.Invoke(tmp, null)
|
/// </summary>
|
/// <param name="paramArray"></param>
|
/// <returns></returns>
|
public dynamic getResult(List<double> paramArray)
|
{
|
object result;
|
result = mi.Invoke(tmp, new object[] { paramArray });
|
return result;
|
//return mi;
|
|
}
|
|
public dynamic ChangeParam(LogicModelParams param, WdnmoParam wParam,GeneticParams gParam,calcParam cParam)
|
{
|
if (mi == null || tmp == null) return null;
|
dynamic r = (mi.Invoke(tmp, new object[] { param, wParam, gParam, cParam }));
|
return r;
|
}
|
//public dynamic ChangeResult(LogicModelParams param, WdnmoParam wParam,GeneticParams gParam,List<Result> results)
|
//{
|
// return ( mi.Invoke(tmp, new object[] { param, wParam, gParam, results }));
|
//}
|
/// <summary>
|
/// 返回函数进行调用,调用方式resultMehodInfo.Invoke(tmp, null)
|
/// </summary>
|
/// <param name="paramArray"></param>
|
/// <returns></returns>
|
public dynamic getResult(Dictionary<string, Dictionary<string, string>> dict_param)
|
{
|
object result = mi.Invoke(tmp, new object[] { dict_param });
|
|
return result;
|
//return mi;
|
|
|
}
|
|
/// <summary>
|
/// 返回函数进行调用,调用方式resultMehodInfo.Invoke(tmp, null)
|
/// </summary>
|
/// <param name="paramArray"></param>
|
/// <returns></returns>
|
public dynamic getResult(dict dict_node,dict dict_link)
|
{
|
object result = mi.Invoke(tmp, new object[] { dict_node,dict_link });
|
|
return result;
|
//return mi;
|
|
|
}
|
|
|
/// <summary>
|
/// 返回函数进行调用,调用方式resultMehodInfo.Invoke(tmp, null)
|
/// </summary>
|
/// <param name="paramArray"></param>
|
/// <returns></returns>
|
public string checkMethod()
|
{
|
Random rand = new Random();
|
List<double> paramArray = new List<double>();
|
for(int i=0;i<paramNum;i++)
|
{
|
paramArray.Add(rand.NextDouble());
|
}
|
|
|
try
|
{
|
object result = mi.Invoke(tmp, new object[] { paramArray.ToArray() });
|
if (!(result is double))
|
{
|
return "函数值的返回类型错误";
|
}
|
}
|
catch(Exception e)
|
{
|
return e.Message;
|
}
|
|
|
|
return null;
|
//return mi;
|
}
|
}
|
public class EvalTemplate
|
{
|
public static string CommonUse = @"
|
using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Text;
|
using System.IO;
|
using System.Linq;
|
|
using System.Drawing;
|
|
using Hydro.CommonBase;
|
";
|
public static string TempCode_function = CommonUse+ @"
|
namespace CoustomEval
|
{
|
[Serializable]
|
class myLib
|
{
|
public double myMethod(List<double> paramArray)
|
{
|
{0}
|
}
|
}
|
}";
|
static string TempCode_Total = CommonUse + @"
|
namespace CoustomEval
|
{
|
[Serializable]
|
class myLib
|
{
|
{0}
|
}
|
}";
|
static string functionTemp = @"
|
public double TMethod{1}(List<double> paramArray)
|
{
|
{0}
|
}
|
";
|
List<string> codes_Total = new List<string>();
|
|
public int Count { get { return codes_Total.Count; } }
|
|
public void Add_code(string code)
|
{
|
string Fcode = functionTemp.Replace("{0}", code).Replace("{1}",codes_Total.Count.ToString());
|
codes_Total.Add(Fcode);
|
}
|
|
public string Get_code()
|
{
|
string fCodes= string.Join("\r\n",codes_Total.ToArray());
|
return TempCode_Total.Replace("{0}",fCodes);
|
}
|
|
public void Clear()
|
{
|
codes_Total.Clear();
|
}
|
public static void fi()
|
{
|
|
}
|
|
public static string TempCode_Set = CommonUse+@"
|
namespace CoustomEval
|
{
|
[Serializable]
|
class myLib
|
{
|
public dict myMethod(dict map,dict map_link)
|
{
|
{0}
|
}
|
}
|
}
|
";
|
public static string TempCode_PreTreat = CommonUse+@"
|
namespace CoustomEval
|
{
|
[Serializable]
|
class myLib
|
{
|
public object myMethod(LogicModelParams param, WdnmoParam wParam,GeneticParams gParam,calcParam cParam)
|
{
|
{0}
|
}
|
}
|
}
|
";
|
}
|
|
}
|