mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-28 18:43:23 +08:00
补充了Library的注释
This commit is contained in:
@@ -5,12 +5,12 @@ using System.Threading.Tasks;
|
|||||||
namespace Serein.Library.Api
|
namespace Serein.Library.Api
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 流程上下文
|
/// 流程上下文,包含运行环境接口,可以通过注册环境事件或调用环境接口,实现在流程运行时更改流程行为。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IDynamicContext
|
public interface IDynamicContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运行环境
|
/// 运行环境,包含IOC容器。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IFlowEnvironment Env { get; }
|
IFlowEnvironment Env { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Api
|
namespace Serein.Library.Api
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 空接口
|
||||||
|
/// </summary>
|
||||||
public interface IDynamicFlowNode
|
public interface IDynamicFlowNode
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ using Serein.Library.NodeFlow.Tool;
|
|||||||
namespace Serein.Library.Api
|
namespace Serein.Library.Api
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 触发器必须使用该接口作为返回值,同时必须用Task泛型表示,否则将不会进行等待触发。
|
/// <para>触发器必须使用该接口作为返回值,同时必须用Task泛型表示,否则将不会进行等待触发。</para>
|
||||||
|
/// <para>即使大多数时候,触发器传出的数据可能是任何一种数据类型,导致其泛型参数可能是无意义的 object / dynamic 。</para>
|
||||||
|
/// <para>但在确定传出类型的场景下,至少可以保证数据一定为某个类型。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IFlipflopContext<out TResult>
|
public interface IFlipflopContext<out TResult>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,19 +4,23 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Serein.Library.Api
|
namespace Serein.Library.Api
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <para>单例模式IOC容器,内部维护了一个实例字典,默认使用类型的FullName作为Key,如果以“接口-实现类”的方式注册,那么将使用接口类型的FullName作为Key。</para>
|
||||||
|
/// <para>当某个类型注册绑定成功后,将不会因为其它地方尝试注册相同类型的行为导致类型被重新创建。</para>
|
||||||
|
/// </summary>
|
||||||
public interface ISereinIOC
|
public interface ISereinIOC
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 清空
|
/// 慎用,重置IOC容器,除非再次注册绑定,否则将导致不能创建注入依赖类的临时对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ISereinIOC Reset();
|
ISereinIOC Reset();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册实例
|
/// 注册实例,如果确定了params,那么将使用params入参构建实例对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ISereinIOC Register(Type type, params object[] parameters);
|
ISereinIOC Register(Type type, params object[] parameters);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册实例
|
/// 通过泛型的方式注册实例,如果确定了params,那么将使用params入参构建实例对象。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
@@ -25,58 +29,65 @@ namespace Serein.Library.Api
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册接口的实例
|
/// 注册接口的实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TService"></typeparam>
|
/// <typeparam name="TService">接口类型</typeparam>
|
||||||
/// <typeparam name="TImplementation"></typeparam>
|
/// <typeparam name="TImplementation">实例类型</typeparam>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ISereinIOC Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService;
|
ISereinIOC Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService;
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 获取或创建并注入目标类型,会记录到IOC容器中。
|
|
||||||
///// </summary>
|
|
||||||
//T GetOrRegisterInstantiate<T>();
|
|
||||||
///// <summary>
|
|
||||||
///// 获取或创建并注入目标类型,会记录到IOC容器中。
|
|
||||||
///// </summary>
|
|
||||||
//object GetOrRegisterInstantiate(Type type);
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取类型的实例
|
/// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
object Get(Type type);
|
object Get(Type type);
|
||||||
|
/// <summary>
|
||||||
|
/// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。
|
||||||
|
/// </summary>
|
||||||
T Get<T>();
|
T Get<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取指定名称的实例
|
/// <para>获取指定名称的实例。</para>
|
||||||
|
/// <para>正常情况下应该使用 Get(Type type) / T Get<T>() 进行获取,但如果需要的实例是以CustomRegisterInstance()进行的登记,则需要通过这种方法进行获取。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="key"></param>
|
/// <param name="key">登记实例时使用的Key</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
T Get<T>(string key);
|
T Get<T>(string key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过名称注册实例
|
/// 指定一个Key登记一个实例。如果实例中需要注入的依赖项,需要将needInjectProperty设置为true。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">注入名称</param>
|
/// <param name="key">注入名称</param>
|
||||||
/// <param name="instance">实例对象</param>
|
/// <param name="instance">实例对象</param>
|
||||||
/// <param name="needInjectProperty">是否需要注入依赖项</param>
|
/// <param name="needInjectProperty">是否需要注入依赖项</param>
|
||||||
void CustomRegisterInstance(string key, object instance, bool needInjectProperty = true);
|
/// <returns>是否注册成功</returns>
|
||||||
|
bool CustomRegisterInstance(string key, object instance, bool needInjectProperty = true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于临时实例的创建,不注册到IOC容器中,依赖项注入失败时也不记录。
|
/// <para>创建实例并注入依赖项,不会注册到IOC容器中。</para>
|
||||||
|
/// <para>使用场景:例如 View 的构造函数中需要创建 ViewModel,而 ViewModel 存在注册过的依赖项,可以通过该接口进行创建</para>
|
||||||
|
/// <para></para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
object Instantiate(Type type);
|
object Instantiate(Type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于临时实例的创建,不注册到IOC容器中,依赖项注入失败时也不记录。
|
/// <para>创建实例并注入依赖项,不会注册到IOC容器中。</para>
|
||||||
|
/// <para>使用场景:例如 View 的构造函数中需要创建 ViewModel,而 ViewModel 存在注册过的依赖项,可以通过该接口进行创建</para>
|
||||||
|
/// <para></para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
T Instantiate<T>();
|
T Instantiate<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 实例化注册的类型,并注入依赖项
|
/// 通过已注册的类型,生成依赖关系,然后依次实例化并注入依赖项,最后登记到容器中。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
ISereinIOC Build();
|
ISereinIOC Build();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从容器中获取某个类型的实例进行运行
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="action"></param>
|
||||||
|
/// <returns></returns>
|
||||||
ISereinIOC Run<T>(Action<T> action);
|
ISereinIOC Run<T>(Action<T> action);
|
||||||
ISereinIOC Run<T1, T2>(Action<T1, T2> action);
|
ISereinIOC Run<T1, T2>(Action<T1, T2> action);
|
||||||
ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action);
|
ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action);
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Serein.Library.Entity
|
|
||||||
{
|
|
||||||
// 每次发生调用的时候,将当前节点调用信息拷贝一份,
|
|
||||||
// 调用完成后释放?
|
|
||||||
// 参数信息
|
|
||||||
public class CallChainInfo
|
|
||||||
{
|
|
||||||
public List<string> CallGuid { get; }
|
|
||||||
public List<object[]> InvokeData { get; }
|
|
||||||
public List<object> ResultData { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,8 @@ using static Serein.Library.Utils.EmitHelper;
|
|||||||
namespace Serein.Library.Entity
|
namespace Serein.Library.Entity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 委托描述
|
/// Emit创建的委托描述,用于WebApi、WebSocket、NodeFlow动态调用方法的场景。
|
||||||
|
/// 一般情况下你无须内部细节,只需要调用 Invoke() 方法即可。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DelegateDetails
|
public class DelegateDetails
|
||||||
{
|
{
|
||||||
@@ -28,6 +29,13 @@ namespace Serein.Library.Entity
|
|||||||
public Delegate EmitDelegate { get => _emitDelegate; }
|
public Delegate EmitDelegate { get => _emitDelegate; }
|
||||||
public EmitMethodType EmitMethodType { get => _emitMethodType; }
|
public EmitMethodType EmitMethodType { get => _emitMethodType; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步等待Emit创建的委托。
|
||||||
|
/// 需要注意的是,传入的实例必须包含创建委托的方法信息,传入的参数也必须符合方法入参信息。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="instance">实例</param>
|
||||||
|
/// <param name="args">入参</param>
|
||||||
|
/// <returns>返回值</returns>
|
||||||
public async Task<object> Invoke(object instance, object[] args)
|
public async Task<object> Invoke(object instance, object[] args)
|
||||||
{
|
{
|
||||||
object result = null;
|
object result = null;
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ namespace Serein.Library.Entity
|
|||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 参数
|
/// 节点入参参数信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExplicitData
|
public class ExplicitData
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 索引
|
/// 参数索引
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Index { get; set; }
|
public int Index { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -23,67 +23,49 @@ namespace Serein.Library.Entity
|
|||||||
ActingInstance = ActingInstance,
|
ActingInstance = ActingInstance,
|
||||||
ActingInstanceType = ActingInstanceType,
|
ActingInstanceType = ActingInstanceType,
|
||||||
MethodDynamicType = MethodDynamicType,
|
MethodDynamicType = MethodDynamicType,
|
||||||
// MethodGuid = Guid.NewGuid().ToString(),
|
|
||||||
MethodTips = MethodTips,
|
MethodTips = MethodTips,
|
||||||
ReturnType = ReturnType,
|
ReturnType = ReturnType,
|
||||||
MethodName = MethodName,
|
MethodName = MethodName,
|
||||||
MethodLockName = MethodLockName,
|
MethodLockName = MethodLockName,
|
||||||
IsNetFramework = IsNetFramework,
|
|
||||||
IsProtectionParameter = IsProtectionParameter,
|
IsProtectionParameter = IsProtectionParameter,
|
||||||
ExplicitDatas = ExplicitDatas?.Select(it => it.Clone()).ToArray(),
|
ExplicitDatas = ExplicitDatas?.Select(it => it.Clone()).ToArray(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否保护参数
|
/// 是否保护参数(仅视觉效果参数,不影响运行实现)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsProtectionParameter { get; set; } = false;
|
public bool IsProtectionParameter { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 作用实例的类型
|
/// 作用实例的类型(多个相同的节点将拥有相同的类型)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public Type ActingInstanceType { get; set; }
|
public Type ActingInstanceType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 作用实例
|
/// 作用实例(多个相同的节点将会共享同一个实例)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public object ActingInstance { get; set; }
|
public object ActingInstance { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 方法GUID
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
// public string MethodGuid { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 方法名称
|
/// 方法名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public string MethodName { get; set; }
|
public string MethodName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 方法委托
|
|
||||||
/// </summary>
|
|
||||||
// public Delegate MethodDelegate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点类型
|
/// 节点类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NodeType MethodDynamicType { get; set; }
|
public NodeType MethodDynamicType { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 锁名称
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 锁名称(暂未实现)
|
||||||
|
/// </summary>
|
||||||
public string MethodLockName { get; set; }
|
public string MethodLockName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 方法说明
|
/// 方法说明
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public string MethodTips { get; set; }
|
public string MethodTips { get; set; }
|
||||||
|
|
||||||
|
|
||||||
@@ -99,91 +81,7 @@ namespace Serein.Library.Entity
|
|||||||
|
|
||||||
public Type ReturnType { get; set; }
|
public Type ReturnType { get; set; }
|
||||||
|
|
||||||
public bool IsNetFramework { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//public bool IsCanConnect(Type returnType)
|
|
||||||
//{
|
|
||||||
// if (ExplicitDatas.Length == 0)
|
|
||||||
// {
|
|
||||||
// // 目标不需要传参,可以舍弃结果?
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// var types = ExplicitDatas.Select(it => it.DataType).ToArray();
|
|
||||||
// // 检查返回类型是否是元组类型
|
|
||||||
// if (returnType.IsGenericType && IsValueTuple(returnType))
|
|
||||||
// {
|
|
||||||
|
|
||||||
// return CompareGenericArguments(returnType, types);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// int index = 0;
|
|
||||||
// if (types[index] == typeof(DynamicContext))
|
|
||||||
// {
|
|
||||||
// index++;
|
|
||||||
// if (types.Length == 1)
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // 被连接节点检查自己需要的参数类型,与发起连接的节点比较返回值类型
|
|
||||||
// if (returnType == types[index])
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 检查元组类型
|
|
||||||
///// </summary>
|
|
||||||
///// <param name="type"></param>
|
|
||||||
///// <returns></returns>
|
|
||||||
//private bool IsValueTuple(Type type)
|
|
||||||
//{
|
|
||||||
// if (!type.IsGenericType) return false;
|
|
||||||
|
|
||||||
// var genericTypeDef = type.GetGenericTypeDefinition();
|
|
||||||
// return genericTypeDef == typeof(ValueTuple<>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,,,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,,,,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,,,,,>) ||
|
|
||||||
// genericTypeDef == typeof(ValueTuple<,,,,,,,>);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//private bool CompareGenericArguments(Type returnType, Type[] parameterTypes)
|
|
||||||
//{
|
|
||||||
// var genericArguments = returnType.GetGenericArguments();
|
|
||||||
// var length = parameterTypes.Length;
|
|
||||||
|
|
||||||
// for (int i = 0; i < genericArguments.Length; i++)
|
|
||||||
// {
|
|
||||||
// if (i >= length) return false;
|
|
||||||
|
|
||||||
// if (IsValueTuple(genericArguments[i]))
|
|
||||||
// {
|
|
||||||
// // 如果当前参数也是 ValueTuple,递归检查嵌套的泛型参数
|
|
||||||
// if (!CompareGenericArguments(genericArguments[i], parameterTypes.Skip(i).ToArray()))
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else if (genericArguments[i] != parameterTypes[i])
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Serein.Library.Entity
|
|
||||||
{
|
|
||||||
public class NodeData
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,9 @@ using static Serein.Library.Utils.ChannelFlowInterrupt;
|
|||||||
|
|
||||||
namespace Serein.Library.Entity
|
namespace Serein.Library.Entity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点调试设置,用于中断节点的运行
|
||||||
|
/// </summary>
|
||||||
public class NodeDebugSetting
|
public class NodeDebugSetting
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -13,32 +16,24 @@ namespace Serein.Library.Entity
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsEnable { get; set; } = true;
|
public bool IsEnable { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否监视数据改变
|
|
||||||
/// </summary>
|
|
||||||
// public bool IsMonitorFlowData { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 中断级别,暂时停止继续执行后继分支。
|
/// 中断级别,暂时停止继续执行后继分支。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public InterruptClass InterruptClass { get; set; } = InterruptClass.None;
|
public InterruptClass InterruptClass { get; set; } = InterruptClass.None;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 中断表达式
|
|
||||||
/// </summary>
|
|
||||||
// public List<string> InterruptExpressions { get; } = new List<string>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取消中断的回调函数
|
/// 取消中断的回调函数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action CancelInterruptCallback { get; set; }
|
public Action CancelInterruptCallback { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 中断Task
|
/// 中断Task(用来取消中断)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<Task<CancelType>> GetInterruptTask { get; set; }
|
public Func<Task<CancelType>> GetInterruptTask { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 中断级别,暂时停止继续执行后继分支。
|
/// 中断级别,暂时停止继续执行后继分支。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -5,9 +5,16 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Serein.Library.Entity
|
namespace Serein.Library.Entity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 节点DLL依赖类,如果一个项目中引入了多个DLL,需要放置在同一个文件夹中
|
||||||
|
/// </summary>
|
||||||
public class NodeLibrary
|
public class NodeLibrary
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 路径
|
||||||
|
/// </summary>
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
public Assembly Assembly { get; set; }
|
public Assembly Assembly { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Serein.Library.Entity
|
|||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 项目输出文件
|
/// 项目保存文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SereinProjectData
|
public class SereinProjectData
|
||||||
{
|
{
|
||||||
@@ -39,11 +39,6 @@ namespace Serein.Library.Entity
|
|||||||
|
|
||||||
public NodeInfo[] Nodes { get; set; }
|
public NodeInfo[] Nodes { get; set; }
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 区域集合
|
|
||||||
///// </summary>
|
|
||||||
|
|
||||||
//public Region[] Regions { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +184,9 @@ namespace Serein.Library.Entity
|
|||||||
public bool IsSelect { get; set; }
|
public bool IsSelect { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示参数
|
||||||
|
/// </summary>
|
||||||
public class Parameterdata
|
public class Parameterdata
|
||||||
{
|
{
|
||||||
public bool State { get; set; }
|
public bool State { get; set; }
|
||||||
@@ -213,13 +211,5 @@ namespace Serein.Library.Entity
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 区域
|
|
||||||
/// </summary>
|
|
||||||
public class Region
|
|
||||||
{
|
|
||||||
public string guid { get; set; }
|
|
||||||
public NodeInfo[] ChildNodes { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Serein.Library.Enums
|
namespace Serein.Library.Enums
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示了两个节点之间的连接关系,同时表示节点运行完成后,所会执行的下一个节点类型。
|
||||||
|
/// </summary>
|
||||||
public enum ConnectionType
|
public enum ConnectionType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认属性
|
/// 将不会继续执行
|
||||||
/// </summary>
|
/// </summary>
|
||||||
None,
|
None,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Enums
|
namespace Serein.Library.Enums
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 触发器说明
|
||||||
|
/// </summary>
|
||||||
public enum FlipflopStateType
|
public enum FlipflopStateType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -22,7 +24,7 @@ namespace Serein.Library.Enums
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Error,
|
Error,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 取消
|
/// 取消(将不会执行触发器的后继节点)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Cancel,
|
Cancel,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,35 +6,67 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Enums
|
namespace Serein.Library.Enums
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用来判断该方法属于什么节点,使运行环境决定方法的运行逻辑
|
||||||
|
/// </summary>
|
||||||
public enum NodeType
|
public enum NodeType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化,流程启动时执行(不生成节点)
|
/// 初始化,流程启动时执行(不生成节点)
|
||||||
|
/// <para>可以异步等待</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Init,
|
Init,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 开始载入,流程启动时执行(不生成节点)
|
/// 开始载入,流程启动时执行(不生成节点)
|
||||||
|
/// <para>可以异步等待</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Loading,
|
Loading,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 结束,流程结束时执行(不生成节点)
|
/// 结束,流程结束时执行(不生成节点)
|
||||||
|
/// <para>可以异步等待</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Exit,
|
Exit,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 触发器(返回值必须为Task<IFlipflopContext<TResult>>)
|
/// <para>触发器节点,必须为标记在可异步等待的方法,建议与继承了 FlowTriggerk<TEnum> 的实例对象搭配使用</para>
|
||||||
|
/// <para>方法返回值必须为Task<IFlipflopContext<TResult>>,若为其它返回值,将不会创建节点。</para>
|
||||||
|
/// <para>触发器根据在分支中的位置,分为两种类型:流程分支中的触发器、全局触发器</para>
|
||||||
|
/// <para>一般的触发器:存在于分支某处,也可能是分支的终点,但一定不是流程的起点与分支的起点。</para>
|
||||||
|
/// <para>一般的触发器行为:在当前分支中执行一次之后不再执行,一般用于等待某个操作的响应。</para>
|
||||||
|
/// <para>一般的触发器入参:如果使用了 FlowTriggerk<TEnum> ,就会至少有一个枚举类型的参数,参数类型与 TEnum 泛型一致。</para>
|
||||||
|
/// <para>全局触发器:没有上游分支、同时并非流程的起始节点。</para>
|
||||||
|
/// <para>全局触发器行为:全局触发器会循环执行,直到流程结束。</para>
|
||||||
|
/// <para>一般的触发器入参:如果使用了 FlowTriggerk<TEnum> ,就会至少有一个枚举类型的参数,参数类型与 TEnum 泛型一致。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Flipflop,
|
Flipflop,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 条件
|
/// <para>动作节点,可以异步等待</para>
|
||||||
/// </summary>
|
/// <para>如果不显式的设置入参数据(例如文本、@Get取值表达式),就会默认使用该节点的运行时上一个节点的数据。</para>
|
||||||
Condition,
|
/// <para>假如上一节点是某个对象,但入参需要的是对象中某个属性/字段,则建议使用取值表达式、表达式节点获取所需要的数据。</para>
|
||||||
/// <summary>
|
/// <para>关于@Get取值表达式的使用方法:</para>
|
||||||
/// 动作
|
/// <para>public class UserInfo </para>
|
||||||
|
/// <para>{ </para>
|
||||||
|
/// <para> public string Name; // 取值表达式:@Get .Name </para>
|
||||||
|
/// <para> public string[] PhoneNums; // 获取第1项的取值表达式:@Get .PhoneNums[0] </para>
|
||||||
|
/// <para> } </para>
|
||||||
|
/// <para>取值表达式可以符合直觉的如此获取实例成员:@Get .Data.Array[2].Data......</para>
|
||||||
|
/// <para>格式说明:@Get大小写不敏感,然后空一格,需要标记“.”,然后才是获取成员名称(成员名称大小写敏感)。</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Action,
|
Action,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class UserInfo
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public int Id;
|
||||||
|
public string[] PhoneNums;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成的节点控件
|
/// 生成的节点控件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -4,23 +4,33 @@ using System.CodeDom;
|
|||||||
namespace Serein.Library.Ex
|
namespace Serein.Library.Ex
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 触发器
|
/// 触发器异常
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class FlipflopException: Exception
|
public class FlipflopException: Exception
|
||||||
{
|
{
|
||||||
public enum CancelClass
|
public enum CancelClass
|
||||||
{
|
{
|
||||||
// 取消当前分支的继续执行
|
/// <summary>
|
||||||
|
/// 取消触发器当前所在分支的继续执行
|
||||||
|
/// </summary>
|
||||||
Branch,
|
Branch,
|
||||||
// 取消整个触发器流程的再次执行
|
/// <summary>
|
||||||
|
/// 取消整个触发器流程的再次执行(用于停止全局触发器)
|
||||||
|
/// </summary>
|
||||||
Flow,
|
Flow,
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 是否已取消
|
||||||
|
/// </summary>
|
||||||
public bool IsCancel { get; }
|
public bool IsCancel { get; }
|
||||||
public CancelClass Clsss { get; }
|
/// <summary>
|
||||||
|
/// 取消类型
|
||||||
|
/// </summary>
|
||||||
|
public CancelClass Type { get; }
|
||||||
public FlipflopException(string message, bool isCancel = true,CancelClass clsss = CancelClass.Branch) :base(message)
|
public FlipflopException(string message, bool isCancel = true,CancelClass clsss = CancelClass.Branch) :base(message)
|
||||||
{
|
{
|
||||||
IsCancel = isCancel;
|
IsCancel = isCancel;
|
||||||
Clsss = clsss;
|
Type = clsss;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Utils
|
namespace Serein.Library.Utils
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 类型转换工具类
|
||||||
|
/// </summary>
|
||||||
public static class ConvertHelper
|
public static class ConvertHelper
|
||||||
{
|
{
|
||||||
public static TResult ToConvert<TResult>(this object data)
|
public static TResult ToConvert<TResult>(this object data)
|
||||||
|
|||||||
@@ -8,12 +8,24 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Serein.Library.Utils
|
namespace Serein.Library.Utils
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Emit创建委托工具类
|
||||||
|
/// </summary>
|
||||||
public class EmitHelper
|
public class EmitHelper
|
||||||
{
|
{
|
||||||
public enum EmitMethodType
|
public enum EmitMethodType
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 普通的方法。如果方法返回void时,将会返回null。
|
||||||
|
/// </summary>
|
||||||
Func,
|
Func,
|
||||||
|
/// <summary>
|
||||||
|
/// 无返回值的异步方法
|
||||||
|
/// </summary>
|
||||||
Task,
|
Task,
|
||||||
|
/// <summary>
|
||||||
|
/// 有返回值的异步方法
|
||||||
|
/// </summary>
|
||||||
HasResultTask,
|
HasResultTask,
|
||||||
}
|
}
|
||||||
public static bool IsGenericTask(Type returnType, out Type taskResult)
|
public static bool IsGenericTask(Type returnType, out Type taskResult)
|
||||||
@@ -38,11 +50,6 @@ namespace Serein.Library.Utils
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//public static Delegate CreateDynamicMethod<T>(MethodInfo methodInfo)
|
|
||||||
//{
|
|
||||||
// return CreateDynamicMethod(methodInfo);
|
|
||||||
//}
|
|
||||||
|
|
||||||
public static EmitMethodType CreateDynamicMethod( MethodInfo methodInfo,out Delegate @delegate)
|
public static EmitMethodType CreateDynamicMethod( MethodInfo methodInfo,out Delegate @delegate)
|
||||||
{
|
{
|
||||||
bool IsTask = IsGenericTask(methodInfo.ReturnType, out var taskGenericsType);
|
bool IsTask = IsGenericTask(methodInfo.ReturnType, out var taskGenericsType);
|
||||||
|
|||||||
@@ -6,11 +6,22 @@ using System.Text;
|
|||||||
|
|
||||||
namespace Serein.Library.Utils
|
namespace Serein.Library.Utils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举工具类,用于枚举转换器
|
||||||
|
/// </summary>
|
||||||
public static class EnumHelper
|
public static class EnumHelper
|
||||||
{
|
{
|
||||||
public static bool TryConvertEnum<T>(this string value, out T result) where T : struct, Enum
|
/// <summary>
|
||||||
|
/// 将字符串的字面量枚举值,转为对应的枚举值
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEnum">枚举</typeparam>
|
||||||
|
/// <param name="value">枚举字面量</param>
|
||||||
|
/// <param name="result">返回的枚举值</param>
|
||||||
|
/// <returns>是否转换成功</returns>
|
||||||
|
public static bool TryConvertEnum<TEnum>(this string value, out TEnum result) where TEnum : struct, Enum
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out T tempResult) && Enum.IsDefined(typeof(T), tempResult))
|
if (!string.IsNullOrEmpty(value) && Enum.TryParse(value, true, out TEnum tempResult) && Enum.IsDefined(typeof(TEnum), tempResult))
|
||||||
{
|
{
|
||||||
result = tempResult;
|
result = tempResult;
|
||||||
return true;
|
return true;
|
||||||
@@ -18,6 +29,15 @@ namespace Serein.Library.Utils
|
|||||||
result = default;
|
result = default;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从枚举值的 BindValueAttribute 特性中 获取绑定的参数(用于绑定了某些内容的枚举值)
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||||
|
/// <typeparam name="TResult">返回类型</typeparam>
|
||||||
|
/// <param name="enumValue">枚举值</param>
|
||||||
|
/// <param name="valueSelector">选择什么参数</param>
|
||||||
|
/// <returns></returns>
|
||||||
public static TResult GetBoundValue<TEnum, TResult>(TEnum enumValue, Func<BindValueAttribute, object> valueSelector)
|
public static TResult GetBoundValue<TEnum, TResult>(TEnum enumValue, Func<BindValueAttribute, object> valueSelector)
|
||||||
where TEnum : Enum
|
where TEnum : Enum
|
||||||
{
|
{
|
||||||
@@ -26,6 +46,7 @@ namespace Serein.Library.Utils
|
|||||||
|
|
||||||
return attribute != null ? (TResult)valueSelector(attribute) : default;
|
return attribute != null ? (TResult)valueSelector(attribute) : default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object GetBoundValue(Type enumType,object enumValue, Func<BindValueAttribute, object> valueSelector)
|
public static object GetBoundValue(Type enumType,object enumValue, Func<BindValueAttribute, object> valueSelector)
|
||||||
{
|
{
|
||||||
var fieldInfo = enumType.GetField(enumValue.ToString());
|
var fieldInfo = enumType.GetField(enumValue.ToString());
|
||||||
@@ -34,6 +55,16 @@ namespace Serein.Library.Utils
|
|||||||
return attribute != null ? valueSelector(attribute) : default;
|
return attribute != null ? valueSelector(attribute) : default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从枚举值从获取自定义特性的成员,并自动转换类型
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||||
|
/// <typeparam name="TAttribute">自定义特性类型</typeparam>
|
||||||
|
/// <typeparam name="TResult">返回类型</typeparam>
|
||||||
|
/// <param name="enumValue">枚举值</param>
|
||||||
|
/// <param name="valueSelector">特性成员选择</param>
|
||||||
|
/// <returns></returns>
|
||||||
public static TResult GetBoundValue<TEnum, TAttribute, TResult>(TEnum enumValue,
|
public static TResult GetBoundValue<TEnum, TAttribute, TResult>(TEnum enumValue,
|
||||||
Func<TAttribute, TResult> valueSelector)
|
Func<TAttribute, TResult> valueSelector)
|
||||||
where TEnum : Enum
|
where TEnum : Enum
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Serein.Library.Utils
|
namespace Serein.Library.Utils
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 基于类型创建表达式树反射委托
|
/// 基于类型创建表达式树反射委托(目前已使用EmitHelper代替)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ExpressionHelper
|
public static class ExpressionHelper
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -117,20 +117,21 @@ namespace Serein.Library.Utils
|
|||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
/// <param name="instance"></param>
|
/// <param name="instance"></param>
|
||||||
/// <param name="needInjectProperty"></param>
|
/// <param name="needInjectProperty"></param>
|
||||||
public void CustomRegisterInstance(string key, object instance, bool needInjectProperty = true)
|
public bool CustomRegisterInstance(string key, object instance, bool needInjectProperty = true)
|
||||||
{
|
{
|
||||||
// 不存在时才允许创建
|
// 不存在时才允许创建
|
||||||
if (!_dependencies.ContainsKey(key))
|
if (_dependencies.ContainsKey(key))
|
||||||
{
|
{
|
||||||
_dependencies.TryAdd(key, instance);
|
return false;
|
||||||
}
|
}
|
||||||
|
_dependencies.TryAdd(key, instance);
|
||||||
if (needInjectProperty)
|
if (needInjectProperty)
|
||||||
{
|
{
|
||||||
InjectDependencies(instance); // 注入实例需要的依赖项
|
InjectDependencies(instance); // 注入实例需要的依赖项
|
||||||
}
|
}
|
||||||
InjectUnfinishedDependencies(key, instance); // 检查是否存在其它实例需要该类型
|
InjectUnfinishedDependencies(key, instance); // 检查是否存在其它实例需要该类型
|
||||||
OnIOCMembersChanged?.Invoke(new IOCMembersChangedEventArgs(key, instance));
|
OnIOCMembersChanged?.Invoke(new IOCMembersChangedEventArgs(key, instance));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
public object Get(Type type)
|
public object Get(Type type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,15 +51,13 @@ namespace Net462DllTest.LogicControl
|
|||||||
#region 触发器节点
|
#region 触发器节点
|
||||||
|
|
||||||
[NodeAction(NodeType.Flipflop, "等待变量更新")]
|
[NodeAction(NodeType.Flipflop, "等待变量更新")]
|
||||||
public async Task<IFlipflopContext<dynamic>> WaitTask(PlcVarName varName = PlcVarName.ErrorCode)
|
public async Task<IFlipflopContext<object>> WaitTask(PlcVarName varName = PlcVarName.ErrorCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var triggerData = await MyPlc.CreateTaskAsync<dynamic>(varName);
|
var triggerData = await MyPlc.CreateTaskAsync<object>(varName);
|
||||||
|
|
||||||
await Console.Out.WriteLineAsync($"PLC变量触发器[{varName}]传递数据:{triggerData}");
|
await Console.Out.WriteLineAsync($"PLC变量触发器[{varName}]传递数据:{triggerData}");
|
||||||
return new FlipflopContext<dynamic>(FlipflopStateType.Succeed, triggerData);
|
return new FlipflopContext<object>(FlipflopStateType.Succeed, triggerData);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,18 +51,7 @@ namespace Net462DllTest.LogicControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
//[NodeAction(NodeType.Action, "打开窗体(指定枚举值)")]
|
|
||||||
//public void OpenForm(IDynamicContext context,
|
|
||||||
// FromValue fromId = FromValue.FromWorkBenchView,
|
|
||||||
// bool isTop = true)
|
|
||||||
//{
|
|
||||||
// var fromType = EnumHelper.GetBoundValue<FromValue, Type>(fromId, attr => attr.Value);
|
|
||||||
// if (fromType is null) return;
|
|
||||||
// if (context.Env.IOC.Instantiate(fromType) is Form form)
|
|
||||||
// {
|
|
||||||
// ViewManagement.OpenView(form, isTop);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
[NodeAction(NodeType.Action, "打开窗体(转换器)")]
|
[NodeAction(NodeType.Action, "打开窗体(转换器)")]
|
||||||
public void OpenForm2([EnumTypeConvertor(typeof(FromValue))] Form form, bool isTop = true)
|
public void OpenForm2([EnumTypeConvertor(typeof(FromValue))] Form form, bool isTop = true)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Net462DllTest.Web
|
|||||||
[WebApi(ApiType.POST)]
|
[WebApi(ApiType.POST)]
|
||||||
public dynamic PlcOp([Url] string var, int value)
|
public dynamic PlcOp([Url] string var, int value)
|
||||||
{
|
{
|
||||||
if (EnumHelper.TryConvertEnum<PlcVarName>(var,out var signal))
|
if (EnumHelper.TryConvertEnum<PlcVarName>(var, out var signal))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"外部触发 {signal} 信号,信号内容 : {value} ");
|
Console.WriteLine($"外部触发 {signal} 信号,信号内容 : {value} ");
|
||||||
plcDevice.Trigger(signal, value);// 通过 Web Api 模拟外部输入信号
|
plcDevice.Trigger(signal, value);// 通过 Web Api 模拟外部输入信号
|
||||||
|
|||||||
@@ -1249,11 +1249,11 @@ namespace Serein.NodeFlow
|
|||||||
{
|
{
|
||||||
return sereinIOC.Get<T>(key);
|
return sereinIOC.Get<T>(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ISereinIOC.CustomRegisterInstance(string key, object instance, bool needInjectProperty)
|
|
||||||
|
bool ISereinIOC.CustomRegisterInstance(string key, object instance, bool needInjectProperty)
|
||||||
{
|
{
|
||||||
sereinIOC.CustomRegisterInstance(key, instance, needInjectProperty);
|
return sereinIOC.CustomRegisterInstance(key, instance, needInjectProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
object ISereinIOC.Instantiate(Type type)
|
object ISereinIOC.Instantiate(Type type)
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ namespace Serein.NodeFlow
|
|||||||
catch(FlipflopException ex)
|
catch(FlipflopException ex)
|
||||||
{
|
{
|
||||||
await Console.Out.WriteLineAsync($"触发器[{singleFlipFlopNode.MethodDetails.MethodName}]因非预期异常终止。"+ex.Message);
|
await Console.Out.WriteLineAsync($"触发器[{singleFlipFlopNode.MethodDetails.MethodName}]因非预期异常终止。"+ex.Message);
|
||||||
if (ex.Clsss == FlipflopException.CancelClass.Flow)
|
if (ex.Type == FlipflopException.CancelClass.Flow)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace Serein.NodeFlow.Model
|
|||||||
}
|
}
|
||||||
catch (FlipflopException ex)
|
catch (FlipflopException ex)
|
||||||
{
|
{
|
||||||
if(ex.Clsss == FlipflopException.CancelClass.Flow)
|
if(ex.Type == FlipflopException.CancelClass.Flow)
|
||||||
{
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user