From 87402ec7ea958c9e7d374a0ee31b672ad7e0e39c Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Tue, 18 Mar 2025 12:33:54 +0800
Subject: [PATCH] =?UTF-8?q?NodeMVVMManagement=E4=B8=8D=E5=86=8D=E6=98=AF?=
=?UTF-8?q?=E9=9D=99=E6=80=81=E7=B1=BB=EF=BC=8C=E8=80=8C=E6=98=AF=E8=BF=90?=
=?UTF-8?q?=E8=A1=8C=E7=8E=AF=E5=A2=83=E5=86=85=E9=83=A8=E7=9A=84=E6=88=90?=
=?UTF-8?q?=E5=91=98=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Library/Api/IFlowEnvironment.cs | 5 +-
Library/FlowNode/ContainerFlowEnvironment.cs | 1 +
.../FlowNode}/NodeMVVMManagement.cs | 22 +++---
Library/Serein.Library.csproj | 3 +-
NodeFlow/Env/FlowEnvironment.cs | 13 ++-
NodeFlow/Env/FlowEnvironmentDecorator.cs | 4 +
NodeFlow/Env/RemoteFlowEnvironment.cs | 1 +
NodeFlow/FlowFunc.cs | 2 +-
NodeFlow/Tool/DynamicCompiler.cs | 4 +-
NodeFlow/Tool/FlowLibrary.cs | 14 ++--
NodeFlow/Tool/FlowLibraryManagement.cs | 79 +++++++++++--------
Workbench/MainWindow.xaml.cs | 24 +++---
.../NetScriptNodeControlViewModel.cs | 3 +-
Workbench/Themes/DynamicCompilerView.xaml.cs | 12 +--
14 files changed, 110 insertions(+), 77 deletions(-)
rename {NodeFlow => Library/FlowNode}/NodeMVVMManagement.cs (80%)
diff --git a/Library/Api/IFlowEnvironment.cs b/Library/Api/IFlowEnvironment.cs
index 6dfa618..8b491bd 100644
--- a/Library/Api/IFlowEnvironment.cs
+++ b/Library/Api/IFlowEnvironment.cs
@@ -705,7 +705,10 @@ namespace Serein.Library.Api
///
UIContextOperation UIContextOperation { get; }
-
+ ///
+ /// 节点视图模型管理类
+ ///
+ NodeMVVMManagement NodeMVVMManagement { get; }
#endregion
#region 基本接口
diff --git a/Library/FlowNode/ContainerFlowEnvironment.cs b/Library/FlowNode/ContainerFlowEnvironment.cs
index 400aaf7..97b6aff 100644
--- a/Library/FlowNode/ContainerFlowEnvironment.cs
+++ b/Library/FlowNode/ContainerFlowEnvironment.cs
@@ -40,6 +40,7 @@ namespace Serein.Library
public IFlowEnvironment CurrentEnv => this;
public UIContextOperation UIContextOperation { get; set; }
+ public NodeMVVMManagement NodeMVVMManagement { get; set; }
///
/// 设置在UI线程操作的线程上下文
diff --git a/NodeFlow/NodeMVVMManagement.cs b/Library/FlowNode/NodeMVVMManagement.cs
similarity index 80%
rename from NodeFlow/NodeMVVMManagement.cs
rename to Library/FlowNode/NodeMVVMManagement.cs
index a5a327a..ee7def3 100644
--- a/NodeFlow/NodeMVVMManagement.cs
+++ b/Library/FlowNode/NodeMVVMManagement.cs
@@ -7,32 +7,34 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace Serein.NodeFlow
+namespace Serein.Library
{
///
/// 节点类型
///
public class NodeMVVM
{
+
+
///
/// 节点类型
///
- public required NodeControlType NodeType { get; set; }
+ public NodeControlType NodeType { get; set; }
///
/// 节点Model类型
///
- public required Type ModelType { get; set; }
+ public Type ModelType { get; set; }
///
/// 节点视图控件类型
///
- public Type? ControlType { get; set; }
+ public Type ControlType { get; set; }
///
/// 节点视图VM类型
///
- public Type? ViewModelType { get; set; }
+ public Type ViewModelType { get; set; }
public override string ToString()
{
@@ -43,19 +45,19 @@ namespace Serein.NodeFlow
///
/// 节点 数据、视图、VM 管理
///
- public static class NodeMVVMManagement
+ public class NodeMVVMManagement
{
///
/// 节点对应的控件类型
///
- private static ConcurrentDictionary FlowNodeTypes { get; } = [];
+ private ConcurrentDictionary FlowNodeTypes { get; } = [];
///
/// 注册 Model 类型
///
///
///
- public static bool RegisterModel(NodeControlType type, Type modelType)
+ public bool RegisterModel(NodeControlType type, Type modelType)
{
if(FlowNodeTypes.TryGetValue(type,out var nodeMVVM))
{
@@ -76,7 +78,7 @@ namespace Serein.NodeFlow
///
///
///
- public static bool RegisterUI(NodeControlType type, Type controlType,Type viewModelType)
+ public bool RegisterUI(NodeControlType type, Type controlType,Type viewModelType)
{
if (!FlowNodeTypes.TryGetValue(type, out var nodeMVVM))
{
@@ -94,7 +96,7 @@ namespace Serein.NodeFlow
///
///
///
- public static bool TryGetType(NodeControlType type, out NodeMVVM nodeMVVM)
+ public bool TryGetType(NodeControlType type, out NodeMVVM nodeMVVM)
{
if( FlowNodeTypes.TryGetValue(type, out nodeMVVM))
{
diff --git a/Library/Serein.Library.csproj b/Library/Serein.Library.csproj
index 32f6161..e81bb66 100644
--- a/Library/Serein.Library.csproj
+++ b/Library/Serein.Library.csproj
@@ -12,7 +12,8 @@
https://github.com/fhhyyp/serein-flow
MIT
True
-
+ latest
+
true
true
.\obj\g
diff --git a/NodeFlow/Env/FlowEnvironment.cs b/NodeFlow/Env/FlowEnvironment.cs
index 35c6de0..0b07d23 100644
--- a/NodeFlow/Env/FlowEnvironment.cs
+++ b/NodeFlow/Env/FlowEnvironment.cs
@@ -42,7 +42,7 @@ namespace Serein.NodeFlow.Env
};
this.FlowLibraryManagement = new FlowLibraryManagement(this); // 实例化类库管理
-
+ this.NodeMVVMManagement = new NodeMVVMManagement();
#region 注册基本节点类型
NodeMVVMManagement.RegisterModel(NodeControlType.UI, typeof(SingleUINode)); // 动作节点
@@ -214,6 +214,11 @@ namespace Serein.NodeFlow.Env
///
public UIContextOperation UIContextOperation { get; set; }
+ ///
+ /// 节点视图模型管理类
+ ///
+ public NodeMVVMManagement NodeMVVMManagement { get; set; }
+
///
/// 信息输出等级
///
@@ -654,12 +659,12 @@ namespace Serein.NodeFlow.Env
///
/// 加载本地程序集
///
- ///
- public void LoadLibrary(Assembly assembly)
+ ///
+ public void LoadLibrary(FlowLibrary flowLibrary)
{
try
{
- (var libraryInfo, var mdInfos) = FlowLibraryManagement.LoadLibraryOfPath(assembly);
+ (var libraryInfo, var mdInfos) = FlowLibraryManagement.LoadLibraryOfPath(flowLibrary);
if (mdInfos.Count > 0)
{
UIContextOperation?.Invoke(() => OnDllLoad?.Invoke(new LoadDllEventArgs(libraryInfo, mdInfos))); // 通知UI创建dll面板显示
diff --git a/NodeFlow/Env/FlowEnvironmentDecorator.cs b/NodeFlow/Env/FlowEnvironmentDecorator.cs
index 2597bd1..6fffc02 100644
--- a/NodeFlow/Env/FlowEnvironmentDecorator.cs
+++ b/NodeFlow/Env/FlowEnvironmentDecorator.cs
@@ -82,6 +82,10 @@ namespace Serein.NodeFlow.Env
public IFlowEnvironment CurrentEnv { get => currentFlowEnvironment; }
public UIContextOperation UIContextOperation => currentFlowEnvironment.UIContextOperation;
+ ///
+ /// 节点视图模型管理类
+ ///
+ public NodeMVVMManagement NodeMVVMManagement => currentFlowEnvironment.NodeMVVMManagement;
public ISereinIOC IOC => (ISereinIOC)currentFlowEnvironment;
diff --git a/NodeFlow/Env/RemoteFlowEnvironment.cs b/NodeFlow/Env/RemoteFlowEnvironment.cs
index f4a2f48..ebadaf1 100644
--- a/NodeFlow/Env/RemoteFlowEnvironment.cs
+++ b/NodeFlow/Env/RemoteFlowEnvironment.cs
@@ -83,6 +83,7 @@ namespace Serein.NodeFlow.Env
public IFlowEnvironment CurrentEnv => this;
public UIContextOperation UIContextOperation { get; }
+ public NodeMVVMManagement NodeMVVMManagement { get; }
///
/// 标示是否正在加载项目
diff --git a/NodeFlow/FlowFunc.cs b/NodeFlow/FlowFunc.cs
index 5c39c7f..2609bca 100644
--- a/NodeFlow/FlowFunc.cs
+++ b/NodeFlow/FlowFunc.cs
@@ -43,7 +43,7 @@ namespace Serein.NodeFlow
// 尝试获取需要创建的节点类型
- if (!NodeMVVMManagement.TryGetType(nodeControlType, out var nodeMVVM) || nodeMVVM.ModelType == null)
+ if (!env.NodeMVVMManagement.TryGetType(nodeControlType, out var nodeMVVM) || nodeMVVM.ModelType == null)
{
throw new Exception($"无法创建{nodeControlType}节点,节点类型尚未注册。");
}
diff --git a/NodeFlow/Tool/DynamicCompiler.cs b/NodeFlow/Tool/DynamicCompiler.cs
index 7b563e9..9d3d7fc 100644
--- a/NodeFlow/Tool/DynamicCompiler.cs
+++ b/NodeFlow/Tool/DynamicCompiler.cs
@@ -101,13 +101,13 @@ namespace Serein.NodeFlow.Tool
}
return null;
}
+
ms.Seek(0, SeekOrigin.Begin);
+ var t12 = AppContext.BaseDirectory;
var assembly = Assembly.Load(ms.ToArray());
var t1 = assembly.Location;
var t = assembly.GetType().Assembly.Location;
-
-
// 保存
compilation.Emit(savePath);
diff --git a/NodeFlow/Tool/FlowLibrary.cs b/NodeFlow/Tool/FlowLibrary.cs
index 56923af..eff5b15 100644
--- a/NodeFlow/Tool/FlowLibrary.cs
+++ b/NodeFlow/Tool/FlowLibrary.cs
@@ -26,7 +26,7 @@ namespace Serein.NodeFlow
///
public class FlowLibrary
{
- private readonly Assembly _assembly;
+ public Assembly Assembly { get; private set; }
@@ -36,16 +36,16 @@ namespace Serein.NodeFlow
public FlowLibrary(Assembly assembly)
{
- this._assembly = assembly;
- this.FullName = Path.GetFileName(_assembly.Location);
+ this.Assembly = assembly;
+ this.FullName = Path.GetFileName(Assembly.Location);
- this.FilePath = _assembly.Location;
+ this.FilePath = Assembly.Location;
}
public FlowLibrary(Assembly assembly,
string filePath)
{
- this._assembly = assembly;
+ this.Assembly = assembly;
this.FullName = Path.GetFileName(filePath); ;
this.FilePath = filePath;
}
@@ -92,7 +92,7 @@ namespace Serein.NodeFlow
///
public NodeLibraryInfo ToInfo()
{
- var assemblyName = _assembly.GetName().Name;
+ var assemblyName = Assembly.GetName().Name;
return new NodeLibraryInfo
{
AssemblyName = assemblyName,
@@ -111,7 +111,7 @@ namespace Serein.NodeFlow
///
public bool LoadAssembly()
{
- Assembly assembly = this._assembly;
+ Assembly assembly = this.Assembly;
#region 检查入参
// 加载DLL,创建 MethodDetails、实例作用对象、委托方法
diff --git a/NodeFlow/Tool/FlowLibraryManagement.cs b/NodeFlow/Tool/FlowLibraryManagement.cs
index e06f953..8ec72bd 100644
--- a/NodeFlow/Tool/FlowLibraryManagement.cs
+++ b/NodeFlow/Tool/FlowLibraryManagement.cs
@@ -49,26 +49,31 @@ namespace Serein.NodeFlow.Tool
var flowAlc = new FlowLibraryAssemblyContext(sereinFlowBaseLibraryPath, Path.GetFileName(libraryfilePath));
var assembly = flowAlc.LoadFromAssemblyPath(libraryfilePath); // 加载指定路径的程序集
- var reulst = LoadDllNodeInfo(assembly);
- if(reulst.Item1 is null || reulst.Item2.Count == 0)
+
+ var flowLibrary = new FlowLibrary(assembly);
+ try
+ {
+ var reulst = LoadFlowLibrary(flowLibrary);
+ return reulst;
+ }
+ catch (Exception)
{
flowAlc?.Unload(); // 卸载程序集
flowAlc = null;
GC.Collect(); // 强制触发GC确保卸载成功
GC.WaitForPendingFinalizers();
- throw new Exception("从文件加载DLL失败:"+ libraryfilePath);
+ throw;
}
- return reulst;
}
///
/// 加载类库
///
- ///
+ ///
///
- public (NodeLibraryInfo, List) LoadLibraryOfPath(Assembly assembly)
+ public (NodeLibraryInfo, List) LoadLibraryOfPath(FlowLibrary flowLibrary)
{
- return LoadDllNodeInfo(assembly);
+ return LoadFlowLibrary(flowLibrary);
}
///
@@ -235,38 +240,48 @@ namespace Serein.NodeFlow.Tool
///
public readonly static string SereinBaseLibrary = $"{nameof(Serein)}.{nameof(Serein.Library)}.dll";
- private (NodeLibraryInfo, List) LoadDllNodeInfo(Assembly assembly)
- {
+ //private (NodeLibraryInfo, List) LoadDllNodeInfo(Assembly assembly)
+ //{
+ // if (assembly.FullName?.ToString().Equals(typeof(IFlowEnvironment).Assembly.FullName?.ToString()) == true)
+ // {
+
+ // // 加载基础依赖
+ // return LoadAssembly(typeof(IFlowEnvironment).Assembly);
+ // }
+ // else
+ // {
+ // try
+ // {
+ // var assembly_result = LoadAssembly(assembly);
+ // return assembly_result;
+ // }
+ // catch (Exception)
+ // {
+ // return (null,[]);
+ // }
+
+ // }
+
+ //}
+
+
+
+ private (NodeLibraryInfo, List) LoadFlowLibrary(FlowLibrary flowLibrary)
+ {
+ var assembly = flowLibrary.Assembly;
if (assembly.FullName?.ToString().Equals(typeof(IFlowEnvironment).Assembly.FullName?.ToString()) == true)
{
// 加载基础依赖
- return LoadAssembly(typeof(IFlowEnvironment).Assembly);
- }
- else
- {
- try
- {
- var assembly_result = LoadAssembly(assembly);
- return assembly_result;
- }
- catch (Exception)
- {
- return (null,[]);
- }
-
+ flowLibrary = new FlowLibrary(typeof(IFlowEnvironment).Assembly);
}
- }
+ var assmblyName = assembly.GetName().Name;
+ if (!string.IsNullOrEmpty(assmblyName) && _myFlowLibrarys.ContainsKey(assmblyName))
+ {
+ throw new Exception($"程序集[{assembly.GetName().FullName}]已经加载过!");
+ }
- private (NodeLibraryInfo, List) LoadAssembly(Assembly assembly)
- {
- if (_myFlowLibrarys.ContainsKey(assembly.GetName().Name))
- {
- throw new Exception($"程序集[{assembly.GetName().FullName}]已经加载过!");
- }
-
- FlowLibrary flowLibrary = new FlowLibrary(assembly);
var loadResult = flowLibrary.LoadAssembly(); // 加载程序集
if (loadResult)
{
diff --git a/Workbench/MainWindow.xaml.cs b/Workbench/MainWindow.xaml.cs
index 58e0d71..12101fd 100644
--- a/Workbench/MainWindow.xaml.cs
+++ b/Workbench/MainWindow.xaml.cs
@@ -164,15 +164,15 @@ namespace Serein.Workbench
IOCObjectViewer.SelectObj += ViewObjectViewer.LoadObjectInformation; // 使选择 IOC容器视图 的某项(对象)时,可以在 数据视图 呈现数据
#region 为 NodeControlType 枚举 不同项添加对应的 Control类型 、 ViewModel类型
- NodeMVVMManagement.RegisterUI(NodeControlType.UI, typeof(UINodeControl), typeof(UINodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.Action, typeof(ActionNodeControl), typeof(ActionNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.Flipflop, typeof(FlipflopNodeControl), typeof(FlipflopNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.ExpOp, typeof(ExpOpNodeControl), typeof(ExpOpNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.ExpCondition, typeof(ConditionNodeControl), typeof(ConditionNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.ConditionRegion, typeof(ConditionRegionControl), typeof(ConditionRegionNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.GlobalData, typeof(GlobalDataControl), typeof(GlobalDataNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.Script, typeof(ScriptNodeControl), typeof(ScriptNodeControlViewModel));
- NodeMVVMManagement.RegisterUI(NodeControlType.NetScript, typeof(NetScriptNodeControl), typeof(NetScriptNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.UI, typeof(UINodeControl), typeof(UINodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.Action, typeof(ActionNodeControl), typeof(ActionNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.Flipflop, typeof(FlipflopNodeControl), typeof(FlipflopNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.ExpOp, typeof(ExpOpNodeControl), typeof(ExpOpNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.ExpCondition, typeof(ConditionNodeControl), typeof(ConditionNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.ConditionRegion, typeof(ConditionRegionControl), typeof(ConditionRegionNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.GlobalData, typeof(GlobalDataControl), typeof(GlobalDataNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.Script, typeof(ScriptNodeControl), typeof(ScriptNodeControlViewModel));
+ EnvDecorator.NodeMVVMManagement.RegisterUI(NodeControlType.NetScript, typeof(NetScriptNodeControl), typeof(NetScriptNodeControlViewModel));
#endregion
@@ -733,7 +733,7 @@ namespace Serein.Workbench
PositionOfUI position = eventArgs.Position;
- if(!NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
+ if(!EnvDecorator.NodeMVVMManagement.TryGetType(nodeModel.ControlType, out var nodeMVVM))
{
SereinEnv.WriteLine(InfoType.INFO, $"无法创建{nodeModel.ControlType}节点,节点类型尚未注册。");
return;
@@ -2707,11 +2707,11 @@ public class FlowLibrary
DynamicCompilerView dynamicCompilerView = new DynamicCompilerView();
dynamicCompilerView.ScriptCode = script;
- dynamicCompilerView.OnCompileComplete = (assembly) =>
+ dynamicCompilerView.OnCompileComplete = (flowLibrary) =>
{
if(EnvDecorator.CurrentEnv is FlowEnvironment environment)
{
- environment.LoadLibrary(assembly);
+ environment.LoadLibrary(flowLibrary);
}
//EnvDecorator.LoadLibrary
};
diff --git a/Workbench/Node/ViewModel/NetScriptNodeControlViewModel.cs b/Workbench/Node/ViewModel/NetScriptNodeControlViewModel.cs
index 5e090ef..e9c8dcb 100644
--- a/Workbench/Node/ViewModel/NetScriptNodeControlViewModel.cs
+++ b/Workbench/Node/ViewModel/NetScriptNodeControlViewModel.cs
@@ -71,9 +71,8 @@ public class FlowLibrary
});
}
- private static void OnCompileComplete(System.Reflection.Assembly assembly)
+ private static void OnCompileComplete(FlowLibrary flowLibrary)
{
- FlowLibrary flowLibrary = new FlowLibrary(assembly);
var loadResult = flowLibrary.LoadAssembly(); // 动态编译完成后加载程序集
if (!loadResult)
{
diff --git a/Workbench/Themes/DynamicCompilerView.xaml.cs b/Workbench/Themes/DynamicCompilerView.xaml.cs
index b205346..4e0d108 100644
--- a/Workbench/Themes/DynamicCompilerView.xaml.cs
+++ b/Workbench/Themes/DynamicCompilerView.xaml.cs
@@ -1,4 +1,5 @@
using Microsoft.Win32;
+using Serein.NodeFlow;
using Serein.NodeFlow.Tool;
using System;
using System.Collections.Generic;
@@ -33,7 +34,7 @@ namespace Serein.Workbench.Themes
///
/// 编译成功回调
///
- public Action OnCompileComplete { get; set; }
+ public Action OnCompileComplete { get; set; }
public DynamicCompilerView()
{
InitializeComponent();
@@ -127,16 +128,17 @@ namespace Serein.Workbench.Themes
try
{
txtErrors.Clear();
- string code = codeEditor.Text;
- Assembly assembly = _compiler.Compile(code, textboxAssemblyName.Text);
-
+ var code = codeEditor.Text;
+ var path = textboxAssemblyName.Text;
+ Assembly assembly = _compiler.Compile(code, path);
+ FlowLibrary flowLibrary = new FlowLibrary(assembly, path);
if (assembly != null)
{
txtErrors.Text = "编译成功!";
txtErrors.Background = System.Windows.Media.Brushes.LightGreen;
- OnCompileComplete.Invoke(assembly);
+ OnCompileComplete.Invoke(flowLibrary);
count++;
}
}