using Serein.Library.Api;
using Serein.Library.Core.NodeFlow;
using Serein.Library.Entity;
using Serein.Library.Enums;
using Serein.Library.Utils;
using Serein.Library.Web;
using Serein.NodeFlow.Base;
using Serein.NodeFlow.Model;
using System.ComponentModel.Design;
using System.Runtime.CompilerServices;
using static Serein.Library.Utils.ChannelFlowInterrupt;
namespace Serein.NodeFlow
{
///
/// 流程启动器
///
///
///
public class FlowStarter
{
public FlowStarter()
{
SereinIOC = new SereinIOC();
}
///
/// 流程运行状态
///
public enum RunState
{
///
/// 等待开始
///
NoStart,
///
/// 正在运行
///
Running,
///
/// 运行完成
///
Completion,
}
///
/// 控制触发器
///
public const string FlipFlopCtsName = "<>.FlowFlipFlopCts";
public bool IsStopStart = false;
///
/// 运行状态
///
public RunState FlowState { get; private set; } = RunState.NoStart;
public RunState FlipFlopState { get; private set; } = RunState.NoStart;
///
/// 运行时的IOC容器
///
private ISereinIOC SereinIOC { get; } = null;
///
/// 结束运行时需要执行的方法
///
private Action ExitAction { get; set; } = null;
///
/// 运行的上下文
///
private IDynamicContext Context { get; set; } = null;
private void CheckStartState()
{
if (IsStopStart)
{
throw new Exception("停止启动");
}
}
///
/// 开始运行
///
/// 起始节点
/// 运行环境
/// 环境中已加载的所有节点方法
/// 触发器节点
///
public async Task RunAsync(NodeModelBase startNode,
IFlowEnvironment env,
List runNodeMd,
List initMethods,
List loadingMethods,
List exitMethods,
List flipflopNodes)
{
FlowState = RunState.Running; // 开始运行
if (startNode == null) {
FlowState = RunState.Completion; // 不存在起点,退出流程
return;
}
#region 选择运行环境的上下文
// 判断使用哪一种流程上下文
var isNetFramework = false;
if (isNetFramework)
{
Context = new Serein.Library.Framework.NodeFlow.DynamicContext(SereinIOC, env);
}
else
{
Context = new Serein.Library.Core.NodeFlow.DynamicContext(SereinIOC, env); // 从起始节点启动流程时创建上下文
}
#endregion
#region 初始化运行环境的Ioc容器
// 清除节点使用的对象,筛选出需要初始化的方法描述
var thisRuningMds = new List();
thisRuningMds.AddRange(runNodeMd.Where(md => md is not null));
thisRuningMds.AddRange(initMethods.Where(md => md is not null));
thisRuningMds.AddRange(loadingMethods.Where(md => md is not null));
thisRuningMds.AddRange(exitMethods.Where(md => md is not null));
// .AddRange(initMethods).AddRange(loadingMethods).a
foreach (var nodeMd in thisRuningMds)
{
nodeMd.ActingInstance = null;
}
SereinIOC.Reset(); // 开始运行时清空ioc中注册的实例
// 初始化ioc容器中的类型对象
foreach (var md in thisRuningMds)
{
if (md.ActingInstanceType != null)
{
SereinIOC.Register(md.ActingInstanceType);
}
else
{
await Console.Out.WriteLineAsync($"{md.MethodName} - 没有类型声明");
IsStopStart = true;
}
}
CheckStartState();
SereinIOC.Build(); // 流程启动前的初始化
foreach (var md in thisRuningMds)
{
md.ActingInstance = SereinIOC.GetOrRegisterInstantiate(md.ActingInstanceType);
if(md.ActingInstance is null)
{
await Console.Out.WriteLineAsync($"{md.MethodName} - 无法获取类型[{md.ActingInstanceType}]的实例");
IsStopStart = true;
}
}
CheckStartState();
//foreach (var md in flipflopNodes.Select(it => it.MethodDetails).ToArray())
//{
// md.ActingInstance = SereinIoc.GetOrCreateServiceInstance(md.ActingInstanceType);
//}
#endregion
#region 检查并修正初始化、加载时、退出时方法作用的对象,保证后续不会报错(已注释)
//foreach (var md in initMethods) // 初始化
//{
// md.ActingInstance ??= Context.SereinIoc.GetOrRegisterInstantiate(md.ActingInstanceType);
//}
//foreach (var md in loadingMethods) // 加载
//{
// md.ActingInstance ??= Context.SereinIoc.GetOrRegisterInstantiate(md.ActingInstanceType);
//}
//foreach (var md in exitMethods) // 初始化
//{
// md.ActingInstance ??= Context.SereinIoc.GetOrRegisterInstantiate(md.ActingInstanceType);
//}
#endregion
#region 执行初始化,绑定IOC容器,再执行加载时
//object?[]? args = [Context];
foreach (var md in initMethods) // 初始化
{
((Action