mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-02 15:50:47 +08:00
准备修改运行环境中类库的依赖结构
This commit is contained in:
@@ -138,15 +138,15 @@ namespace Serein.Library.Api
|
||||
|
||||
public class LoadDllEventArgs : FlowEventArgs
|
||||
{
|
||||
public LoadDllEventArgs(NodeLibrary nodeLibrary, List<MethodDetailsInfo> MethodDetailss)
|
||||
public LoadDllEventArgs(NodeLibraryInfo nodeLibraryInfo, List<MethodDetailsInfo> MethodDetailss)
|
||||
{
|
||||
this.NodeLibrary = nodeLibrary;
|
||||
this.NodeLibraryInfo = nodeLibraryInfo;
|
||||
this.MethodDetailss = MethodDetailss;
|
||||
}
|
||||
/// <summary>
|
||||
/// 已加载了的程序集
|
||||
/// </summary>
|
||||
public NodeLibrary NodeLibrary { get; protected set; }
|
||||
public NodeLibraryInfo NodeLibraryInfo { get; protected set; }
|
||||
/// <summary>
|
||||
/// dll文件中有效的流程方法描述
|
||||
/// </summary>
|
||||
@@ -676,8 +676,8 @@ namespace Serein.Library.Api
|
||||
/// <summary>
|
||||
/// 移除DLL
|
||||
/// </summary>
|
||||
/// <param name="assemblyFullName">程序集的名称</param>
|
||||
bool RemoteDll(string assemblyFullName);
|
||||
/// <param name="assemblyName">程序集的名称</param>
|
||||
bool RemoteDll(string assemblyName);
|
||||
|
||||
/// <summary>
|
||||
/// 清理加载的DLL(待更改)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点DLL依赖类,如果一个项目中引入了多个DLL,需要放置在同一个文件夹中
|
||||
/// </summary>
|
||||
public class NodeLibrary
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
public string FilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 依赖类的名称
|
||||
/// </summary>
|
||||
public string FullName{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 对应的程序集
|
||||
/// </summary>
|
||||
public Assembly Assembly { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
108
Library/Entity/NodeLibraryInfo.cs
Normal file
108
Library/Entity/NodeLibraryInfo.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Serein.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// 节点DLL依赖类,如果一个项目中引入了多个DLL,需要放置在同一个文件夹中
|
||||
/// </summary>
|
||||
public class NodeLibraryInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
public string FileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 路径
|
||||
/// </summary>
|
||||
public string FilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属的程序集名称
|
||||
/// </summary>
|
||||
public string AssemblyName{ get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class FlowLibrary
|
||||
{
|
||||
public FlowLibrary(string assemblyName,
|
||||
Action actionOfUnloadAssmbly)
|
||||
{
|
||||
this.AssemblyName = assemblyName;
|
||||
this.actionOfUnloadAssmbly = actionOfUnloadAssmbly;
|
||||
}
|
||||
|
||||
public string AssemblyName { get; }
|
||||
|
||||
//public string AssemblyVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 加载程序集时创建的方法描述
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, MethodDetails> MethodDetailss { get; } = new ConcurrentDictionary<string, MethodDetails>();
|
||||
|
||||
/// <summary>
|
||||
/// 管理通过Emit动态构建的委托
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, DelegateDetails> DelegateDetailss { get; } = new ConcurrentDictionary<string, DelegateDetails>();
|
||||
|
||||
/// <summary>
|
||||
/// 记录不同的注册时机需要自动创建全局唯一实例的类型信息
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<RegisterSequence, Type[]> RegisterTypes { get; } = new ConcurrentDictionary<RegisterSequence, Type[]>();
|
||||
|
||||
|
||||
private readonly Action actionOfUnloadAssmbly;
|
||||
|
||||
/// <summary>
|
||||
/// 卸载当前程序集以及附带的所有信息
|
||||
/// </summary>
|
||||
public void Upload()
|
||||
{
|
||||
actionOfUnloadAssmbly?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 通过方法名称获取对应的Emit委托(元数据),用于动态调用节点对应的方法
|
||||
/// </summary>
|
||||
/// <param name="methodName">方法名称</param>
|
||||
/// <param name="dd">Emit委托</param>
|
||||
/// <returns></returns>
|
||||
public bool GetDelegateDetails(string methodName, out DelegateDetails dd)
|
||||
{
|
||||
return DelegateDetailss.TryGetValue(methodName, out dd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过方法名称获取对应的方法描述(元数据),用于创建节点时,节点实例需要的方法描述
|
||||
/// </summary>
|
||||
/// <param name="methodName">方法名称</param>
|
||||
/// <param name="md">方法描述</param>
|
||||
/// <returns></returns>
|
||||
public bool GetMethodDetails(string methodName, out MethodDetails md)
|
||||
{
|
||||
return MethodDetailss.TryGetValue(methodName, out md);
|
||||
}
|
||||
|
||||
public NodeLibraryInfo ToInfo()
|
||||
{
|
||||
return new NodeLibraryInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -129,7 +129,7 @@ namespace Serein.Library
|
||||
&& index < ParameterDetailss.Length) // 防止下标越界
|
||||
{
|
||||
ParameterDetailss[index] = null; // 释放对象引用
|
||||
var tmp = ArrayHelper.RemoteToArray(ParameterDetailss, index); // 新增;
|
||||
var tmp = ArrayHelper.RemoteToArray<ParameterDetails>(ParameterDetailss, index); // 新增;
|
||||
UpdateParamIndex(ref tmp);
|
||||
ParameterDetailss = tmp; // 新增
|
||||
return true;
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace Serein.Library
|
||||
public class MethodDetailsInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 属于哪个DLL文件
|
||||
/// 属于哪个程序集
|
||||
/// </summary>
|
||||
public string LibraryName { get; set; }
|
||||
public string AssemblyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 方法名称
|
||||
|
||||
@@ -33,9 +33,9 @@ namespace Serein.Library
|
||||
public class LibraryMds
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序集FullName
|
||||
/// 程序集名称
|
||||
/// </summary>
|
||||
public string LibraryName { get; set; }
|
||||
public string AssemblyName { get; set; }
|
||||
/// <summary>
|
||||
/// 相关的方法详情
|
||||
/// </summary>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>1.0.19</Version>
|
||||
<TargetFrameworks>net8.0;net462</TargetFrameworks>
|
||||
<!--<TargetFrameworks>net8.0</TargetFrameworks>-->
|
||||
<TargetFrameworks>net8.0;net462</TargetFrameworks>
|
||||
<BaseOutputPath>D:\Project\C#\DynamicControl\SereinFlow\.Output</BaseOutputPath>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Title>SereinFow</Title>
|
||||
@@ -37,8 +37,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<ProjectReference Include="..\Serein.Library.MyGenerator\Serein.Library.NodeGenerator.csproj" OutputItemType="Analyzer" />
|
||||
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.Reactive" Version="6.0.1" />
|
||||
<PackageReference Include="System.Threading.Channels" Version="8.0.0" />
|
||||
@@ -60,4 +58,8 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Serein.Library.MyGenerator\Serein.Library.NodeGenerator.csproj " OutputItemType="Analyzer" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -223,24 +223,45 @@ namespace Serein.NodeFlow.Env
|
||||
#endregion
|
||||
|
||||
#region 私有变量
|
||||
|
||||
/// <summary>
|
||||
/// 通过程序集名称管理动态加载的程序集,用于节点创建提供方法描述,流程运行时提供Emit委托
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, FlowLibrary> FlowLibrarys { get; } = [];
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Library 与 MethodDetailss的依赖关系
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<NodeLibrary, List<MethodDetails>> MethodDetailsOfLibrarys { get; } = [];
|
||||
public ConcurrentDictionary<NodeLibraryInfo, List<MethodDetails>> MethodDetailsOfLibraryInfos { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存储已加载的程序集
|
||||
/// <para>存储已加载的程序集</para>
|
||||
/// <para>Key:程序集的FullName </para>
|
||||
/// <para>Value:构造的方法信息</para>
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, NodeLibrary> Librarys { get; } = [];
|
||||
public ConcurrentDictionary<string, NodeLibraryInfo> LibraryInfos { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存储已加载的方法信息。描述所有DLL中NodeAction特性的方法的原始副本
|
||||
/// <para>存储已加载的方法信息。描述所有DLL中NodeAction特性的方法的原始副本</para>
|
||||
/// <para>Key:反射时获取的MethodInfo.MehtodName</para>
|
||||
/// <para>Value:构造的方法信息</para>
|
||||
/// </summary>
|
||||
public ConcurrentDictionary<string, MethodDetails> MethodDetailss { get; } = [];
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 容器管理
|
||||
/// 从dll中加载的类的注册类型
|
||||
/// </summary>
|
||||
private Dictionary<RegisterSequence, List<Type>> AutoRegisterTypes { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存放所有通过Emit加载的委托
|
||||
/// md.Methodname - delegate
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, DelegateDetails> MethodDelegates { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// IOC对象容器管理
|
||||
/// </summary>
|
||||
private readonly SereinIOC sereinIOC;
|
||||
|
||||
@@ -255,18 +276,7 @@ namespace Serein.NodeFlow.Env
|
||||
/// </summary>
|
||||
private List<SingleFlipflopNode> FlipflopNodes { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 从dll中加载的类的注册类型
|
||||
/// </summary>
|
||||
private Dictionary<RegisterSequence, List<Type>> AutoRegisterTypes { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 存放委托
|
||||
///
|
||||
/// md.Methodname - delegate
|
||||
/// </summary>
|
||||
|
||||
private ConcurrentDictionary<string, DelegateDetails> MethodDelegates { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 起始节点私有属性
|
||||
@@ -470,28 +480,28 @@ namespace Serein.NodeFlow.Env
|
||||
/// <returns></returns>
|
||||
public async Task<FlowEnvInfo> GetEnvInfoAsync()
|
||||
{
|
||||
Dictionary<NodeLibrary, List<MethodDetailsInfo>> LibraryMds = [];
|
||||
Dictionary<NodeLibraryInfo, List<MethodDetailsInfo>> MdsOfLibraryInfos = [];
|
||||
|
||||
foreach (var mdskv in MethodDetailsOfLibrarys)
|
||||
foreach (var mdskv in MethodDetailsOfLibraryInfos)
|
||||
{
|
||||
var library = mdskv.Key;
|
||||
var mds = mdskv.Value;
|
||||
foreach (var md in mds)
|
||||
{
|
||||
if (!LibraryMds.TryGetValue(library, out var t_mds))
|
||||
if (!MdsOfLibraryInfos.TryGetValue(library, out var t_mds))
|
||||
{
|
||||
t_mds = new List<MethodDetailsInfo>();
|
||||
LibraryMds[library] = t_mds;
|
||||
MdsOfLibraryInfos[library] = t_mds;
|
||||
}
|
||||
var mdInfo = md.ToInfo();
|
||||
mdInfo.LibraryName = library.FullName;
|
||||
mdInfo.AssemblyName = library.AssemblyName;
|
||||
t_mds.Add(mdInfo);
|
||||
}
|
||||
}
|
||||
|
||||
LibraryMds[] libraryMdss = LibraryMds.Select(kv => new LibraryMds
|
||||
LibraryMds[] libraryMdss = MdsOfLibraryInfos.Select(kv => new LibraryMds
|
||||
{
|
||||
LibraryName = kv.Key.FullName,
|
||||
AssemblyName = kv.Key.AssemblyName,
|
||||
Mds = kv.Value.ToArray()
|
||||
}).ToArray();
|
||||
var project = await GetProjectInfoAsync();
|
||||
@@ -716,7 +726,7 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
var projectData = new SereinProjectData()
|
||||
{
|
||||
Librarys = Librarys.Values.Select(lib => lib.ToLibrary()).ToArray(),
|
||||
Librarys = LibraryInfos.Values.Select(lib => lib.ToLibrary()).ToArray(),
|
||||
Nodes = NodeModels.Values.Select(node => node.ToInfo()).Where(info => info is not null).ToArray(),
|
||||
StartNode = NodeModels.Values.FirstOrDefault(it => it.IsStart)?.Guid,
|
||||
};
|
||||
@@ -738,11 +748,11 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 移除DLL
|
||||
/// </summary>
|
||||
/// <param name="assemblyFullName"></param>
|
||||
/// <param name="assemblyName"></param>
|
||||
/// <returns></returns>
|
||||
public bool RemoteDll(string assemblyFullName)
|
||||
public bool RemoteDll(string assemblyName)
|
||||
{
|
||||
var library = Librarys.Values.FirstOrDefault(nl => assemblyFullName.Equals(nl.FullName));
|
||||
var library = LibraryInfos.Values.FirstOrDefault(nl => assemblyName.Equals(nl.AssemblyName));
|
||||
if (library is null)
|
||||
{
|
||||
return false;
|
||||
@@ -761,7 +771,7 @@ namespace Serein.NodeFlow.Env
|
||||
return true; // 当前无节点,可以直接删除
|
||||
}
|
||||
|
||||
if (MethodDetailsOfLibrarys.TryGetValue(library, out var mds)) // 存在方法
|
||||
if (MethodDetailsOfLibraryInfos.TryGetValue(library, out var mds)) // 存在方法
|
||||
{
|
||||
foreach (var md in mds)
|
||||
{
|
||||
@@ -778,7 +788,7 @@ namespace Serein.NodeFlow.Env
|
||||
{
|
||||
MethodDetailss.TryRemove(md.MethodName, out _);
|
||||
}
|
||||
MethodDetailsOfLibrarys.TryRemove(library, out _);
|
||||
MethodDetailsOfLibraryInfos.TryRemove(library, out _);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -1395,35 +1405,56 @@ namespace Serein.NodeFlow.Env
|
||||
/// <param name="dllPath"></param>
|
||||
private void LoadDllNodeInfo(string dllPath)
|
||||
{
|
||||
(var nodeLibrary, var registerTypes, var mdlist) = LoadAssembly(dllPath);
|
||||
if (nodeLibrary is not null && mdlist.Count > 0)
|
||||
|
||||
var fileName = Path.GetFileName(dllPath);
|
||||
AssemblyLoadContext flowAlc = new AssemblyLoadContext(fileName, true);
|
||||
flowAlc.LoadFromAssemblyPath(dllPath); // 加载指定路径的程序集
|
||||
|
||||
foreach(var assemblt in flowAlc.Assemblies)
|
||||
{
|
||||
Librarys.TryAdd(nodeLibrary.FullName, nodeLibrary);
|
||||
MethodDetailsOfLibrarys.TryAdd(nodeLibrary, mdlist);
|
||||
|
||||
foreach (var md in mdlist)
|
||||
(var registerTypes, var mdlist) = LoadAssembly(assemblt);
|
||||
if (mdlist.Count > 0)
|
||||
{
|
||||
MethodDetailss.TryAdd(md.MethodName, md);
|
||||
}
|
||||
|
||||
foreach (var kv in registerTypes)
|
||||
{
|
||||
if (!AutoRegisterTypes.TryGetValue(kv.Key, out var types))
|
||||
var nodeLibraryInfo = new NodeLibraryInfo
|
||||
{
|
||||
types = new List<Type>();
|
||||
AutoRegisterTypes.Add(kv.Key, types);
|
||||
//Assembly = assembly,
|
||||
AssemblyName = assemblt.FullName,
|
||||
FileName = Path.GetFileName(dllPath),
|
||||
FilePath = dllPath,
|
||||
};
|
||||
|
||||
LibraryInfos.TryAdd(nodeLibraryInfo.AssemblyName, nodeLibraryInfo);
|
||||
MethodDetailsOfLibraryInfos.TryAdd(nodeLibraryInfo, mdlist);
|
||||
|
||||
foreach (var md in mdlist)
|
||||
{
|
||||
MethodDetailss.TryAdd(md.MethodName, md);
|
||||
}
|
||||
types.AddRange(kv.Value);
|
||||
}
|
||||
var mdInfos = mdlist.Select(md => md.ToInfo()).ToList(); // 转换成方法信息
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
UIContextOperation?.Invoke(() => OnDllLoad?.Invoke(new LoadDllEventArgs(nodeLibrary, mdInfos))); // 通知UI创建dll面板显示
|
||||
foreach (var kv in registerTypes)
|
||||
{
|
||||
if (!AutoRegisterTypes.TryGetValue(kv.Key, out var types))
|
||||
{
|
||||
types = new List<Type>();
|
||||
AutoRegisterTypes.Add(kv.Key, types);
|
||||
}
|
||||
types.AddRange(kv.Value);
|
||||
}
|
||||
var mdInfos = mdlist.Select(md => md.ToInfo()).ToList(); // 转换成方法信息
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
UIContextOperation?.Invoke(() => OnDllLoad?.Invoke(new LoadDllEventArgs(nodeLibraryInfo, mdInfos))); // 通知UI创建dll面板显示
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1477,18 +1508,17 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// 动态加载程序集
|
||||
/// </summary>
|
||||
/// <param name="dllPath"></param>
|
||||
/// <param name="assembly">程序集本身</param>
|
||||
/// <returns></returns>
|
||||
private (NodeLibrary?, Dictionary<RegisterSequence, List<Type>>, List<MethodDetails>) LoadAssembly(string dllPath)
|
||||
private (Dictionary<RegisterSequence, List<Type>>, List<MethodDetails>) LoadAssembly(Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
//FlowLibraryLoader flowLibraryLoader = new FlowLibraryLoader(dllPath);
|
||||
//Assembly assembly = flowLibraryLoader.LoadFromAssemblyPath(dllPath);
|
||||
Assembly assembly = Assembly.LoadFrom(dllPath); // 加载DLL文件
|
||||
List<Type> types = assembly.GetTypes().ToList(); // 获取程序集中的所有类型
|
||||
|
||||
#region 获取所有需要注册的类型
|
||||
Dictionary<RegisterSequence, List<Type>> autoRegisterTypes = new Dictionary<RegisterSequence, List<Type>>();
|
||||
foreach (Type type in types)
|
||||
{
|
||||
@@ -1504,25 +1534,29 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region 获取 DynamicFlow 特性的流程控制器,如果没有返回空
|
||||
List<(Type, string)> scanTypes = types.Select(t =>
|
||||
{
|
||||
if (t.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
|
||||
&& dynamicFlowAttribute.Scan == true)
|
||||
{
|
||||
return (t, dynamicFlowAttribute.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
}).Where(it => it.t is not null).ToList();
|
||||
{
|
||||
if (t.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
|
||||
&& dynamicFlowAttribute.Scan == true)
|
||||
{
|
||||
return (t, dynamicFlowAttribute.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
}).Where(it => it.t is not null).ToList();
|
||||
if (scanTypes.Count == 0)
|
||||
{
|
||||
return (null, [], []);
|
||||
return ([], []);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 创建对应的方法元数据
|
||||
List<MethodDetails> methodDetails = new List<MethodDetails>();
|
||||
// 遍历扫描的类型
|
||||
foreach ((var type, var flowName) in scanTypes)
|
||||
@@ -1552,23 +1586,16 @@ namespace Serein.NodeFlow.Env
|
||||
Console.WriteLine($"节点委托创建失败:{md.MethodName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
var nodeLibrary = new NodeLibrary
|
||||
{
|
||||
FullName = assembly.GetName().FullName,
|
||||
Assembly = assembly,
|
||||
FileName = Path.GetFileName(dllPath),
|
||||
FilePath = dllPath,
|
||||
};
|
||||
//LoadedAssemblies.Add(assembly); // 将加载的程序集添加到列表中
|
||||
//LoadedAssemblyPaths.Add(dllPath); // 记录加载的DLL路径
|
||||
return (nodeLibrary, autoRegisterTypes, methodDetails);
|
||||
|
||||
return (autoRegisterTypes, methodDetails);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
return (null, [], []);
|
||||
return ([], []);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -307,9 +307,9 @@ namespace Serein.NodeFlow.Env
|
||||
}
|
||||
|
||||
|
||||
public bool RemoteDll(string assemblyFullName)
|
||||
public bool RemoteDll(string assemblyName)
|
||||
{
|
||||
return currentFlowEnvironment.RemoteDll(assemblyFullName);
|
||||
return currentFlowEnvironment.RemoteDll(assemblyName);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveConnectInvokeAsync(string fromNodeGuid, string toNodeGuid, ConnectionInvokeType connectionType)
|
||||
|
||||
@@ -87,16 +87,17 @@ namespace Serein.NodeFlow.Env
|
||||
/// <summary>
|
||||
/// 程序集封装依赖
|
||||
/// </summary>
|
||||
/// <param name="library"></param>
|
||||
/// <param name="libraryInfo"></param>
|
||||
/// <returns></returns>
|
||||
public static Library.Library ToLibrary(this Library.NodeLibrary library)
|
||||
public static Library.Library ToLibrary(this Library.NodeLibraryInfo libraryInfo)
|
||||
{
|
||||
var tmp = library.Assembly.ManifestModule.Name;
|
||||
//var tmp = library.Assembly.ManifestModule.Name;
|
||||
return new Library.Library
|
||||
{
|
||||
AssemblyName = library.Assembly.GetName().Name,
|
||||
FileName = library.FileName,
|
||||
FilePath = library.FilePath,
|
||||
AssemblyName = libraryInfo.AssemblyName,
|
||||
//AssemblyName = library.Assembly.GetName().Name,
|
||||
FileName = libraryInfo.FileName,
|
||||
FilePath = libraryInfo.FilePath,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,11 @@ namespace Serein.NodeFlow.Env
|
||||
return prjectInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 远程环境下加载项目
|
||||
/// </summary>
|
||||
/// <param name="flowEnvInfo"></param>
|
||||
/// <param name="filePath"></param>
|
||||
public void LoadProject(FlowEnvInfo flowEnvInfo, string filePath)
|
||||
{
|
||||
Console.WriteLine("加载远程环境");
|
||||
@@ -120,13 +125,13 @@ namespace Serein.NodeFlow.Env
|
||||
var libmds = flowEnvInfo.LibraryMds;
|
||||
foreach (var lib in libmds)
|
||||
{
|
||||
NodeLibrary nodeLibrary = new NodeLibrary
|
||||
NodeLibraryInfo nodeLibraryInfo = new NodeLibraryInfo
|
||||
{
|
||||
FullName = lib.LibraryName,
|
||||
AssemblyName = lib.AssemblyName,
|
||||
FilePath = "Remote",
|
||||
};
|
||||
var mdInfos = lib.Mds.ToList();
|
||||
UIContextOperation?.Invoke(() => OnDllLoad?.Invoke(new LoadDllEventArgs(nodeLibrary, mdInfos))); // 通知UI创建dll面板显示
|
||||
UIContextOperation?.Invoke(() => OnDllLoad?.Invoke(new LoadDllEventArgs(nodeLibraryInfo, mdInfos))); // 通知UI创建dll面板显示
|
||||
foreach (var mdInfo in mdInfos)
|
||||
{
|
||||
MethodDetailss.TryAdd(mdInfo.MethodName, new MethodDetails(mdInfo)); // 从DLL读取时生成元数据
|
||||
@@ -397,7 +402,7 @@ namespace Serein.NodeFlow.Env
|
||||
Console.WriteLine("远程环境尚未实现的接口:LoadDll");
|
||||
}
|
||||
|
||||
public bool RemoteDll(string assemblyFullName)
|
||||
public bool RemoteDll(string assemblyName)
|
||||
{
|
||||
// 尝试移除远程环境中的加载了的依赖
|
||||
Console.WriteLine("远程环境尚未实现的接口:RemoteDll");
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace Serein.NodeFlow.Tool
|
||||
{
|
||||
private Assembly _pluginAssembly;
|
||||
|
||||
public string FullName => _pluginAssembly.FullName;
|
||||
|
||||
/// <summary>
|
||||
/// 加载程序集
|
||||
/// </summary>
|
||||
@@ -35,6 +37,12 @@ namespace Serein.NodeFlow.Tool
|
||||
return null; // 保持默认加载行为
|
||||
}
|
||||
|
||||
|
||||
public List<Type> LoadFlowTypes()
|
||||
{
|
||||
return _pluginAssembly.GetTypes().ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否对程序集的引用
|
||||
/// </summary>
|
||||
|
||||
@@ -19,6 +19,7 @@ public static class NodeMethodDetailsHelper
|
||||
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => m.GetCustomAttribute<NodeActionAttribute>()?.Scan == true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建方法信息
|
||||
/// </summary>
|
||||
@@ -250,22 +251,6 @@ public static class NodeMethodDetailsHelper
|
||||
IsParams = hasParams, // 判断是否为可变参数
|
||||
};
|
||||
|
||||
//string explicitTypeName = GetExplicitTypeName(explicitParemType);
|
||||
//var items = GetExplicitItems(explicitParemType, explicitTypeName);
|
||||
//if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
|
||||
//return new ParameterDetails
|
||||
//{
|
||||
// IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
|
||||
// Index = index, // 索引
|
||||
// ExplicitTypeName = explicitTypeName, // Select/Bool/Value
|
||||
// ExplicitType = explicitParemType,// 显示的入参类型
|
||||
// Convertor = func, // 转换器
|
||||
// DataType = dataType, // 实际的入参类型
|
||||
// Name = parameterInfo.Name,
|
||||
// DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
||||
// Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量
|
||||
// IsParams = hasParams, // 判断是否为可变参数
|
||||
//};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -316,10 +316,10 @@ namespace Serein.Workbench
|
||||
/// </summary>
|
||||
private void FlowEnvironment_DllLoadEvent(LoadDllEventArgs eventArgs)
|
||||
{
|
||||
NodeLibrary nodeLibrary = eventArgs.NodeLibrary;
|
||||
NodeLibraryInfo nodeLibraryInfo = eventArgs.NodeLibraryInfo;
|
||||
List<MethodDetailsInfo> methodDetailss = eventArgs.MethodDetailss;
|
||||
|
||||
var dllControl = new DllControl(nodeLibrary);
|
||||
var dllControl = new DllControl(nodeLibraryInfo);
|
||||
|
||||
foreach (var methodDetailsInfo in methodDetailss)
|
||||
{
|
||||
@@ -341,7 +341,7 @@ namespace Serein.Workbench
|
||||
var menu = new ContextMenu();
|
||||
menu.Items.Add(CreateMenuItem("卸载", (s, e) =>
|
||||
{
|
||||
if (this.EnvDecorator.RemoteDll(nodeLibrary.FullName))
|
||||
if (this.EnvDecorator.RemoteDll(nodeLibraryInfo.AssemblyName))
|
||||
{
|
||||
DllStackPanel.Children.Remove(dllControl);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace Serein.Workbench.Node.View
|
||||
/// </summary>
|
||||
public partial class DllControl : UserControl
|
||||
{
|
||||
private readonly NodeLibrary nodeLibrary;
|
||||
private readonly NodeLibraryInfo nodeLibraryInfo;
|
||||
|
||||
public DllControl()
|
||||
{
|
||||
Header = "DLL文件"; // 设置初始值
|
||||
InitializeComponent();
|
||||
}
|
||||
public DllControl(NodeLibrary nodeLibrary)
|
||||
public DllControl(NodeLibraryInfo nodeLibraryInfo)
|
||||
{
|
||||
this.nodeLibrary = nodeLibrary;
|
||||
Header = "DLL name : " + nodeLibrary.FullName;
|
||||
this.nodeLibraryInfo = nodeLibraryInfo;
|
||||
Header = "DLL name : " + nodeLibraryInfo.AssemblyName;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user