mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-02 15:50:47 +08:00
1. 更新了节点入参的条件判断:入参类型为IFlowContext(流程上下文)时禁止创建参数来源连接。
2. [Script]脚本节点移除了“getFlowContext”内置方法,改为自动识别入参名称为“context""flowContext""flow_context",如果是,将自动使用 IFlowContext 类型参数(运行时自动给定) 3. NodeFlow项目中,FlowLibraryService添加了GetType(string)以及TryGetType(string,Type?)方法,用于流程环境搜索外部加载的程序集类型。
This commit is contained in:
@@ -168,15 +168,57 @@ namespace Serein.Library
|
||||
IsParams = info.IsParams;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 禁止将 IFlowContext 类型显式入参设置为 true
|
||||
/// </summary>
|
||||
/// <param name="__isAllow"></param>
|
||||
/// <param name="newValue"></param>
|
||||
partial void BeforeTheIsExplicitData(ref bool __isAllow, bool newValue)
|
||||
{
|
||||
if(DataType == typeof(IFlowContext))
|
||||
if(DataType == typeof(IFlowContext) && newValue == true)
|
||||
{
|
||||
__isAllow = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 脚本节点的类型缓存。
|
||||
/// </summary>
|
||||
private Type? cacheType;
|
||||
private bool cacheIsExplicit;
|
||||
|
||||
/// <summary>
|
||||
/// 脚本节点的名称变更为流程上下文时,调整 DataType 和 IsExplicitData 的值。
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <param name="newValue"></param>
|
||||
partial void OnNameChanged(string oldValue, string newValue)
|
||||
{
|
||||
if (NodeModel is null)
|
||||
return;
|
||||
if (NodeModel.ControlType == NodeControlType.Script)
|
||||
{
|
||||
var isIgnore = StringComparison.OrdinalIgnoreCase;
|
||||
if ("context".Equals(newValue, isIgnore) ||
|
||||
"flowcontext".Equals(newValue, isIgnore) ||
|
||||
"flow_context".Equals(newValue, isIgnore))
|
||||
{
|
||||
cacheType = DataType;
|
||||
cacheIsExplicit = IsExplicitData;
|
||||
DataType = typeof(IFlowContext);
|
||||
IsExplicitData = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cacheType is not null)
|
||||
{
|
||||
DataType = cacheType;
|
||||
IsExplicitData = cacheIsExplicit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 转为描述
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
|
||||
}
|
||||
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(flowContext);
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext();
|
||||
scriptContext.SetVarValue(dataName, data);
|
||||
|
||||
var result = await getValueScript.InterpreterAsync(scriptContext);
|
||||
@@ -262,7 +262,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
});
|
||||
}
|
||||
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(flowContext);
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext();
|
||||
scriptContext.SetVarValue(dataName, data);
|
||||
|
||||
var result = await conditionScript.InterpreterAsync(scriptContext);
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
|
||||
}
|
||||
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(flowContext);
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext();
|
||||
scriptContext.SetVarValue(dataName, data);
|
||||
|
||||
var result = await getValueScript.InterpreterAsync(scriptContext);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Serein.Library;
|
||||
using Serein.Library.Api;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.NodeFlow.Services;
|
||||
using Serein.Script;
|
||||
using Serein.Script.Node.FlowControl;
|
||||
using System;
|
||||
@@ -49,7 +50,6 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
public SingleScriptNode(IFlowEnvironment environment) : base(environment)
|
||||
{
|
||||
sereinScript = new SereinScript();
|
||||
|
||||
}
|
||||
|
||||
static SingleScriptNode()
|
||||
@@ -195,7 +195,11 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
ScriptArgInfo[] array = JsonHelper.Deserialize<ScriptArgInfo[]>(paramsTypeNameJson);
|
||||
|
||||
string returnTypeName = nodeInfo.CustomData?.ReturnTypeName ?? typeof(object);
|
||||
Type?[] argType = array.Select(item => string.IsNullOrWhiteSpace(item.ArgType) ? null : Type.GetType(item.ArgType) ?? typeof(Unit)).ToArray();
|
||||
|
||||
var flowLibService = Env.IOC.Get<FlowLibraryService>();
|
||||
|
||||
Type?[] argType = array.Select(item => string.IsNullOrWhiteSpace(item.ArgType) ? null : flowLibService.GetType(item.ArgType) ?? typeof(Unit)).ToArray();
|
||||
|
||||
Type? resType = Type.GetType(returnTypeName);
|
||||
for (int i = 0; i < paramCount; i++)
|
||||
{
|
||||
@@ -352,7 +356,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
||||
|
||||
var @params = await flowCallNode.GetParametersAsync(context, token);
|
||||
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(context);
|
||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext();
|
||||
|
||||
if (@params[0] is object[] agrDatas)
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reflection;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -429,6 +430,11 @@ namespace Serein.NodeFlow.Model.Operations
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof(IFlowContext).IsAssignableFrom(ToNode.MethodDetails.ParameterDetailss[ArgIndex].DataType))
|
||||
{
|
||||
SereinEnv.WriteLine(InfoType.WARN, $"连接失败, IFlowContext 流程上下文由运行环境自动注入,作为节点入参时不允许外部给定。起始节点[{FromNode.Guid}],目标节点[{FromNode.Guid}]。");
|
||||
return false;
|
||||
}
|
||||
|
||||
var toNodeArgSourceGuid = ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceNodeGuid; // 目标节点对应参数可能已经有其它连接
|
||||
var toNodeArgSourceType = ToNode.MethodDetails.ParameterDetailss[ArgIndex].ArgDataSourceType;
|
||||
|
||||
@@ -147,6 +147,46 @@ namespace Serein.NodeFlow.Services
|
||||
|
||||
#region 获取流程依赖的相关方法
|
||||
|
||||
/// <summary>
|
||||
/// 搜索类型
|
||||
/// </summary>
|
||||
/// <param name="fullName"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryGetType(string fullName,[NotNullWhen(true)] out Type? type)
|
||||
{
|
||||
var assemblys = _flowLibraryCaches.Values.Select(key => key.Assembly).ToArray();
|
||||
foreach(var assembly in assemblys)
|
||||
{
|
||||
type = assembly.GetType(fullName);
|
||||
if(type is not null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
type = null;
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 搜索类型
|
||||
/// </summary>
|
||||
/// <param name="fullName"></param>
|
||||
/// <returns></returns>
|
||||
public Type? GetType(string fullName)
|
||||
{
|
||||
var assemblys = _flowLibraryCaches.Values.Select(key => key.Assembly).ToArray();
|
||||
Type? type;
|
||||
foreach (var assembly in assemblys)
|
||||
{
|
||||
type = assembly.GetType(fullName);
|
||||
if(type is not null)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取方法描述
|
||||
/// </summary>
|
||||
|
||||
@@ -7,10 +7,6 @@ namespace Serein.Script
|
||||
/// </summary>
|
||||
public interface IScriptInvokeContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本运行的流程上下文,包含了流程上下文和变量等信息
|
||||
/// </summary>
|
||||
IFlowContext FlowContext { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否该退出了(由 TokenSource 控制,用于响应外部发出停止信号)
|
||||
|
||||
@@ -4,15 +4,6 @@ namespace Serein.Script
|
||||
{
|
||||
public sealed class ScriptInvokeContext : IScriptInvokeContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 脚本使用流程上下文
|
||||
/// </summary>
|
||||
/// <param name="flowContext"></param>
|
||||
public ScriptInvokeContext(IFlowContext flowContext)
|
||||
{
|
||||
FlowContext = flowContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 不使用流程上下文
|
||||
/// </summary>
|
||||
@@ -20,10 +11,6 @@ namespace Serein.Script
|
||||
{
|
||||
}
|
||||
|
||||
#pragma warning disable CS8766 // 返回类型中引用类型的为 Null 性与隐式实现的成员不匹配(可能是由于为 Null 性特性)。
|
||||
public IFlowContext? FlowContext{ get; }
|
||||
#pragma warning restore CS8766 // 返回类型中引用类型的为 Null 性与隐式实现的成员不匹配(可能是由于为 Null 性特性)。
|
||||
|
||||
/// <summary>
|
||||
/// 定义的变量
|
||||
/// </summary>
|
||||
|
||||
@@ -13,10 +13,10 @@ namespace Serein.Script
|
||||
public class SereinScriptInterpreter
|
||||
{
|
||||
private readonly Dictionary<ASTNode, Type> symbolInfos;
|
||||
|
||||
/// <summary>
|
||||
/// 缓存对象方法调用节点
|
||||
/// </summary>
|
||||
//private Dictionary<MemberFunctionCallNode, DelegateDetails> MethodNodeDelegateCaches { get; } = new Dictionary<MemberFunctionCallNode, DelegateDetails>();
|
||||
private static Dictionary<ASTNode, DelegateDetails> ASTDelegateDetails { get; } = new Dictionary<ASTNode, DelegateDetails>();
|
||||
|
||||
|
||||
@@ -322,15 +322,6 @@ namespace Serein.Script
|
||||
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
||||
async Task<object?> InterpreterFunctionCallNodeAsync(IScriptInvokeContext context, FunctionCallNode functionCallNode)
|
||||
{
|
||||
// 获取流程上下文
|
||||
if (context.FlowContext != null && functionCallNode.FunctionName.Equals("getFlowContext", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return context.FlowContext;
|
||||
}
|
||||
else if (functionCallNode.FunctionName.Equals("getScriptContext", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
// 获取参数
|
||||
var arguments = functionCallNode.Arguments.Count == 0 ? [] :
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<CheckBox Grid.Column="1" IsChecked="{Binding IsExplicitData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="2,0,2,0" VerticalContentAlignment="Center"/>
|
||||
|
||||
<!--参数类型提示-->
|
||||
<TextBlock Grid.Column="2" Text="{Binding DataType, Converter={StaticResource TypeNameDisplaynConverter}}" Margin="2,0,2,0" VerticalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Text="{Binding DataType, Mode=OneWay, Converter={StaticResource TypeNameDisplaynConverter}}" Margin="2,0,2,0" VerticalAlignment="Center"/>
|
||||
|
||||
|
||||
<!--入参参数名称-->
|
||||
@@ -73,7 +73,7 @@
|
||||
<Setter Property="ContentTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<TextBox MinWidth="50" Text="{Binding Name, Mode=TwoWay}"/>
|
||||
<TextBox MinWidth="50" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
Reference in New Issue
Block a user