1 Star 0 Fork 33

erwa.cn / NScript

forked from 车江毅 / NScript 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
NScriptHelper.cs 6.65 KB
一键复制 编辑 原始数据 按行查看 历史
车江毅 提交于 2016-06-24 10:21 . add project
using BSF.BaseService.NScript.Compiler;
using BSF.BaseService.NScript.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace BSF.BaseService.NScript
{
/// <summary>
/// 编译参数设置
/// </summary>
public class CompilerParams
{
/// <summary>
/// 编译类型
/// </summary>
public EnumCompilerMode EnumCompilerMode = EnumCompilerMode.Assembly;
/// <summary>
/// 编译源码类型 (文件还是文本)
/// </summary>
public EnumSourceType EnumSourceType = EnumSourceType.Code;
/// <summary>
/// 编译内容(文件路径或者Main主文件文本)
/// </summary>
public string CodeOrFileName;
}
public static class NScriptHelper
{
/// <summary>
/// 默认编译结果会缓存,只要传入Main主文件或者文本内容不变,则缓存不失效。
/// 注意:
/// 1)程序集模式:编译持续缓存失效(编译代码内容经常发生改变),缓存不会回收,会造成内存慢慢溢出,内存.net默认无法释放,除非重启程序。
/// 2)应用程序域方式:编译默认也会使用缓存(编译代码内容改变则失效),缓存不会回收,但是通过out compilerResult,运行compilerResult.Dispose,会回收资源,释放缓存,内存就不会溢出了。
/// 若非常频繁使用应用程序域方式编译后又手工Dispose释放,性能自然也不高,所以要自行根据实际情况自行缓存自行释放应用程序域。
/// 使用应用程序域,涉及到跨域通信问题,建议使用[Serializable]标记。
/// 3)Main方式,建议使用在运维环境。代码级别调用则不支持。
/// </summary>
/// <returns></returns>
public static T Run<T>(CompilerParams compilerParams,
string typeName, string methodName, Object[] param, out CompilerResult compilerResult)
{
if(string.IsNullOrEmpty(typeName))
throw new NScriptException("typeName不能为空");
if (string.IsNullOrEmpty(methodName))
throw new NScriptException("methodName不能为空");
if (compilerParams.EnumCompilerMode == EnumCompilerMode.Assembly)
{
compilerResult = RunCompiler(compilerParams);
object obj = compilerResult.Assembly.CreateInstance(typeName);
if (obj == null)
throw new NScriptException("反射对象实例为空");
MethodInfo objMI = obj.GetType().GetMethod(methodName);
if (objMI == null)
throw new NScriptException("反射对象方法为空");
try
{
var r = (T)objMI.Invoke(obj, param);
return r;
}
catch (Exception exp)
{
throw new NScriptException("调用方法出错:" + exp.Message,exp);
}
}
else if (compilerParams.EnumCompilerMode == EnumCompilerMode.AppDomian)
{
try
{
compilerResult = RunCompiler(compilerParams);
AppDomainCallResult<T> result = compilerResult.AppDomianInfo.AppDomainAssemblyLoader.Call<T>(typeName, methodName, param);
if (result.AppDomainCallStatus == AppDomainCallStatus.Error)
{
throw new NScriptException(result.Message == null ? "" : result.Message);
}
return result.Data;
}
catch (Exception exp)
{
throw exp;
}
}
else if (compilerParams.EnumCompilerMode == EnumCompilerMode.Main)
{
throw new NScriptException("不支持动态调用采用Main模式运行,请运行BSF.BaseService.NScript采用命令运行");
}
compilerResult = null;
return default(T);
}
/// <summary>
/// 动态编译并返回编译结果
/// 程序集模式:返回程序集。(代码不变则缓存,缓存无法释放,会慢慢的内存溢出)
/// 应用程序域模式:返回应用程序域(代码不变则缓存,缓存无法释放,会慢慢的内存溢出),也可以通过CompilerResult.Dispose释放则不会内存溢出。
/// Main模式:默认编译为exe,通过AppDomain.CurrentDomain.ExecuteAssembly可以直接打开exe运行。
/// </summary>
/// <param name="compilerParams"></param>
/// <returns></returns>
public static CompilerResult RunCompiler(CompilerParams compilerParams)
{
if (compilerParams.EnumCompilerMode == EnumCompilerMode.Assembly)
{
var compilerInfo = new CompilerInfo().Parse(compilerParams.EnumSourceType, compilerParams.CodeOrFileName);
var compilerResult = new AssemblyCompiler().DoCompiler(compilerInfo);
if (compilerResult.Assembly == null)
throw new NScriptException("编译后程序集为null,编译失败");
return compilerResult;
}
else if (compilerParams.EnumCompilerMode == EnumCompilerMode.AppDomian)
{
var compilerInfo = new CompilerInfo().Parse(compilerParams.EnumSourceType, compilerParams.CodeOrFileName);
var compilerResult = new AppDomainCompiler().DoCompiler(compilerInfo);
if (compilerResult.AppDomianInfo == null || compilerResult.AppDomianInfo.AppDomain == null)
throw new NScriptException("编译后应用程序域为null,编译失败");
if (compilerResult.AppDomianInfo == null || compilerResult.AppDomianInfo.AppDomainAssemblyLoader == null)
throw new NScriptException("编译后应用程序域'调用加载器'为null,编译失败");
return compilerResult;
}
else if (compilerParams.EnumCompilerMode == EnumCompilerMode.Main)
{
var compilerInfo = new CompilerInfo().Parse(compilerParams.EnumSourceType, compilerParams.CodeOrFileName);
var compilerResult = new MainCompiler().DoCompiler(compilerInfo);
if (compilerResult.Assembly == null)
throw new NScriptException("编译后程序集为null,编译失败");
return compilerResult;
}
return null;
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C#
1
https://gitee.com/erwacn/NScript.git
git@gitee.com:erwacn/NScript.git
erwacn
NScript
NScript
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891