From c80f0f85cd4777bb499d2089129790c5c2cde3f0 Mon Sep 17 00:00:00 2001
From: fengjiayi <12821976+ning_xi@user.noreply.gitee.com>
Date: Mon, 30 Sep 2024 16:36:55 +0800
Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99IOC=E5=AE=B9=E5=99=A8?=
=?UTF-8?q?=E7=BB=91=E5=AE=9A=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Library/Utils/SereinIoc.cs | 375 +++++++-----------
Library/Web/Router.cs | 9 +-
Library/Web/WebServer.cs | 7 +-
Net461DllTest/Device/SiemensPlcDevice.cs | 227 ++++++++++-
Net461DllTest/Enums/PlcVarEnum.cs | 34 ++
Net461DllTest/LogicControl/PlcLogicControl.cs | 67 ++--
.../LogicControl/ViewLogicControl.cs | 20 +-
Net461DllTest/Net461DllTest.csproj | 4 +-
.../{OrderSignal.cs => CommandSignal.cs} | 2 +-
Net461DllTest/Signal/CommandSignal_1.cs | 15 +
Net461DllTest/View/FromWorkBenchView.cs | 6 +-
.../ViewModel/FromWorkBenchViewModel.cs | 2 +-
Net461DllTest/Web/CommandController.cs | 47 +++
...piController.cs => CommandController_1.cs} | 16 +-
14 files changed, 530 insertions(+), 301 deletions(-)
rename Net461DllTest/Signal/{OrderSignal.cs => CommandSignal.cs} (88%)
create mode 100644 Net461DllTest/Signal/CommandSignal_1.cs
create mode 100644 Net461DllTest/Web/CommandController.cs
rename Net461DllTest/Web/{ApiController.cs => CommandController_1.cs} (63%)
diff --git a/Library/Utils/SereinIoc.cs b/Library/Utils/SereinIoc.cs
index 02c64a8..ae83f5e 100644
--- a/Library/Utils/SereinIoc.cs
+++ b/Library/Utils/SereinIoc.cs
@@ -5,6 +5,7 @@ using Serein.Library.Web;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Xml;
@@ -12,6 +13,7 @@ using System.Xml.Schema;
namespace Serein.Library.Utils
{
+
///
/// IOC管理容器
///
@@ -44,20 +46,7 @@ namespace Serein.Library.Utils
_unfinishedDependencies = new ConcurrentDictionary>();
}
- ///
- /// 绑定之前进行的默认绑定
- ///
- public void InitRegister()
- {
- _dependencies[typeof(ISereinIOC).FullName] = this;
- Register();
- //foreach (var type in _typeMappings.Values)
- //{
- // Register(type);
- //}
- //Build();
- }
#region 类型的注册
@@ -93,51 +82,6 @@ namespace Serein.Library.Utils
}
#endregion
- ///
- /// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。如果依然无法注册,则返回null。
- ///
- //public T GetOrRegisterInstantiate()
- //{
- // return (T)GetOrRegisterInstantiate(typeof(T));
- //}
-
- /////
- ///// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。如果依然无法注册,则返回null。
- /////
- //public object GetOrRegisterInstantiate(Type type)
- //{
- // // 尝试从容器中获取对象
- // if (!_dependencies.TryGetValue(type.FullName, out object value))
- // {
- // // 容器中不存在目标类型的对象
- // if (type.IsInterface)
- // {
- // if (_typeMappings.TryGetValue(type.FullName, out Type implementationType))
- // {
- // // 是接口类型,存在注册信息
- // Register(type);// 注册类型信息
- // value = Instantiate(implementationType); // 创建实例对象,并注入依赖
- // CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中
- // _typeMappings.TryRemove(type.FullName, out _); // 取消类型的注册信息
- // }
- // else
- // {
- // //需要获取接口类型的实例,但不存在类型注册信息
- // Console.WriteLine("当前需要获取接口,但没有注册实现类的类型,无法创建接口实例");
- // return null;
- // }
- // }
- // else
- // {
- // // 不是接口,直接注册
- // Register(type);// 注册类型信息
- // value = Instantiate(type); // 创建实例对象,并注入依赖
- // CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中
- // }
- // }
- // return value;
- //}
-
///
/// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。
///
@@ -229,134 +173,157 @@ namespace Serein.Library.Utils
_unfinishedDependencies?.Clear();
_typeMappings?.Clear();
_dependencies?.Clear();
- // _waitingForInstantiation?.Clear();
return true;
}
-
- ///
- /// 实例化所有已注册的类型,并尝试绑定
- ///
- ///
- public bool Build2()
+ public class TypeKeyValue
{
- InitRegister();
- // 遍历已注册类型
- foreach (var type in _typeMappings.Values.ToArray())
+ public TypeKeyValue(string name, Type type)
{
- if (!_dependencies.ContainsKey(type.FullName))
- {
- var value = CreateInstance(type); // 绑定时注册的类型如果没有创建实例,则创建对应的实例
- CustomRegisterInstance(type.FullName, value);// 登记到IOC容器中
- }
- _typeMappings.TryRemove(type.FullName, out _); // 移除类型的注册记录
+ this.Type = type;
+ this.Name = name;
}
-
-
- foreach (var instance in _dependencies.Values)
- {
- InjectDependencies(instance); // 绑定时注入实例的依赖项
- }
-
- return true;
+ public string Name { get; set; }
+ public Type Type { get; set; }
}
+ public Dictionary> BuildDependencyTree()
+ {
+ var dependencyMap = new Dictionary>();
+
+ foreach (var typeMapping in _typeMappings)
+ {
+ var constructor = GetConstructorWithMostParameters(typeMapping.Value); // 获取参数最多的构造函数
+ if (constructor != null)
+ {
+ var parameters = constructor.GetParameters()
+ .Select(p => p.ParameterType)
+ .ToList();
+
+ foreach (var param in parameters)
+ {
+ if (!dependencyMap.ContainsKey(param.FullName))
+ {
+ dependencyMap[param.FullName] = new List();
+ }
+ dependencyMap[param.FullName].Add(typeMapping.Key);
+ }
+ }
+ }
+
+ return dependencyMap;
+ }
+ // 获取参数最多的构造函数
+ private ConstructorInfo GetConstructorWithMostParameters(Type type)
+ {
+ return type.GetConstructors()
+ .OrderByDescending(c => c.GetParameters().Length)
+ .FirstOrDefault();
+ }
+ // 生成顺序
+ public List GetCreationOrder(Dictionary> dependencyMap)
+ {
+ var graph = new Dictionary>();
+ var indegree = new Dictionary();
+
+ foreach (var entry in dependencyMap)
+ {
+ var key = entry.Key;
+ if (!graph.ContainsKey(key))
+ {
+ graph[key] = new List();
+ }
+
+ foreach (var dependent in entry.Value)
+ {
+ if (!graph.ContainsKey(dependent))
+ {
+ graph[dependent] = new List();
+ }
+ graph[key].Add(dependent);
+
+ // 更新入度
+ if (!indegree.ContainsKey(dependent))
+ {
+ indegree[dependent] = 0;
+ }
+ indegree[dependent]++;
+ }
+
+ if (!indegree.ContainsKey(key))
+ {
+ indegree[key] = 0;
+ }
+ }
+
+ // 拓扑排序
+ var creationOrder = new List();
+ var queue = new Queue(indegree.Where(x => x.Value == 0).Select(x => x.Key));
+
+ while (queue.Count > 0)
+ {
+ var current = queue.Dequeue();
+ creationOrder.Add(current);
+
+ foreach (var neighbor in graph[current])
+ {
+ indegree[neighbor]--;
+ if (indegree[neighbor] == 0)
+ {
+ queue.Enqueue(neighbor);
+ }
+ }
+ }
+
+ return creationOrder;
+ }
+
+ public object CreateInstance(string typeName)
+ {
+ if (_typeMappings.TryGetValue(typeName, out var type))
+ {
+ var constructor = GetConstructorWithMostParameters(type);
+ var parameters = constructor.GetParameters();
+ var args = new object[parameters.Length];
+
+
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ var fullName = parameters[i].ParameterType.FullName;
+ if (!_dependencies.TryGetValue(fullName, out var argObj))
+ {
+ argObj = CreateInstance(parameters[i].ParameterType.FullName);
+ }
+ args[i] = argObj;
+ }
+ var value = Activator.CreateInstance(type, args);
+ _dependencies[typeName] = value;
+ return value;
+ }
+
+ return null;
+ }
+
+
public bool Build()
{
- InitRegister();
- var graph = new Dictionary>();
- //var graph = new Dictionary>();
+ var dependencyTree = BuildDependencyTree();
+ var creationOrder = GetCreationOrder(dependencyTree);
- // 构建依赖关系图
- foreach (var type in _typeMappings.Values)
+ // 输出创建顺序
+ Debug.WriteLine("创建顺序: " + string.Join(" → ", creationOrder));
+
+ // 创建对象
+ foreach (var typeName in creationOrder)
{
- var constructor = type.GetConstructors()
- .OrderByDescending(c => c.GetParameters().Length)
- .FirstOrDefault();
-
- if (constructor != null)
- {
- var parameters = constructor.GetParameters();
- foreach (var param in parameters)
- {
- var paramTypeName = param.ParameterType.FullName;
- if (!graph.ContainsKey(paramTypeName))
- {
- graph[paramTypeName] = new List();
- }
- graph[paramTypeName].Add(type); // 使用 Type 而不是字符串
- }
- }
+ var value = CreateInstance(typeName);
+
}
-
- // 执行拓扑排序
- var sortedTypes = TopologicalSort(graph);
-
- // 创建实例并注册
- foreach (var type in sortedTypes)
- {
- var typeName = type.FullName;
- if (!_dependencies.ContainsKey(typeName))
- {
-
- var value = CreateInstance(type);
- CustomRegisterInstance(typeName, value);
- //if (graph.ContainsKey(typeName))
- //{
-
-
- //}
- //else
- //{
- // Console.WriteLine("error:"+typeName);
- //}
- }
- else
- {
- Console.WriteLine("not create:" + type);
- }
- }
-
+ _typeMappings.Clear();
return true;
+
}
- ///
- /// 执行拓扑排序
- ///
- ///
- ///
- private List TopologicalSort(Dictionary> graph)
- {
- var sorted = new List();
- var visited = new HashSet();
-
- void Visit(Type node)
- {
- var nodeName = node.FullName;
- if (visited.Contains(nodeName)) return;
- visited.Add(nodeName);
- if (graph.TryGetValue(nodeName, out var neighbors))
- {
- foreach (var neighbor in neighbors)
- {
- Visit(neighbor);
- }
- }
- sorted.Add(node);
- }
-
- foreach (var node in graph.Keys)
- {
- if (!_dependencies.ContainsKey(node))
- {
- var type = _typeMappings[node]; // 获取对应的 Type
- Visit(type);
- }
-
- }
-
- sorted.Reverse(); // 反转以得到正确顺序
- return sorted;
- }
+
#endregion
#region 私有方法
@@ -380,19 +347,6 @@ namespace Serein.Library.Utils
}
}
- ///
- /// 创建实例时,尝试注入到由ioc容器管理、并需要此实例的对象。
- ///
- private object CreateInstance(Type type)
- {
- var constructor = type.GetConstructors().First(); // 获取第一个构造函数
- var parameters = constructor.GetParameters(); // 获取参数列表
- var parameterValues = parameters.Select(param => ResolveDependency(param.ParameterType)).ToArray();
- var instance = Activator.CreateInstance(type, parameterValues);
- InjectUnfinishedDependencies(type.FullName, instance);
- return instance;
- }
-
private object ResolveDependency(Type parameterType)
{
var obj = Get(parameterType);
@@ -459,55 +413,16 @@ namespace Serein.Library.Utils
return isPass;
}
-
- ///
- /// 再次尝试注入目标实例的依赖项
- ///
- //private void TryInstantiateWaitingDependencies()
- //{
- // foreach (var waitingType in _waitingForInstantiation.ToList())
- // {
- // if (_typeMappings.TryGetValue(waitingType.FullName, out var implementationType))
- // {
- // var instance = Instantiate(implementationType);
- // if (instance != null)
- // {
-
- // _dependencies[waitingType.FullName] = instance;
-
- // _waitingForInstantiation.Remove(waitingType);
- // }
- // }
- // }
- //}
- #endregion
-
- #region run()
- //public bool Run(string name, Action action)
- //{
- // var obj = Get(name);
- // if (obj != null)
- // {
- // if(obj is T service)
- // {
- // try
- // {
- // action(service);
- // }
- // catch (Exception ex)
- // {
- // Console.WriteLine(ex.Message);
- // }
- // }
- // }
- // return this;
- //}
-
-
+
public void Run(Action action)
{
var service = Get();
- if (service != null)
+ if (service == null)
+ {
+ throw new Exception("类型没有注册:"+typeof(T).FullName);
+
+ }
+ else
{
action(service);
}
diff --git a/Library/Web/Router.cs b/Library/Web/Router.cs
index 12192e9..a7318f3 100644
--- a/Library/Web/Router.cs
+++ b/Library/Web/Router.cs
@@ -31,10 +31,7 @@ namespace Serein.Library.Web
{
private readonly ISereinIOC SereinIOC; // 用于存储路由信息
- public Router(ISereinIOC SereinIOC)
- {
- this.SereinIOC = SereinIOC;
- }
+
///
/// 控制器实例对象的类型,每次调用都会重新实例化,[Url - ControllerType]
///
@@ -50,9 +47,9 @@ namespace Serein.Library.Web
//private Type PostRequest;
- public Router()
+ public Router(ISereinIOC SereinIOC)
{
-
+ this.SereinIOC = SereinIOC;
_routes = new ConcurrentDictionary>(); // 初始化路由字典
_controllerTypes = new ConcurrentDictionary(); // 初始化控制器实例对象字典
foreach (API method in Enum.GetValues(typeof(API))) // 遍历 HTTP 枚举类型的所有值
diff --git a/Library/Web/WebServer.cs b/Library/Web/WebServer.cs
index e0ff7e0..824d67a 100644
--- a/Library/Web/WebServer.cs
+++ b/Library/Web/WebServer.cs
@@ -20,6 +20,8 @@ namespace Serein.Library.Web
public WebServer(IRouter router)
{
this.Router = router;
+ listener = new HttpListener();
+ requestLimiter = new RequestLimiter(5, 8);
}
@@ -29,11 +31,6 @@ namespace Serein.Library.Web
private HttpListener listener; // HTTP 监听器
private RequestLimiter requestLimiter; //接口防刷
- public WebServer()
- {
- listener = new HttpListener();
- requestLimiter = new RequestLimiter(5, 8);
- }
// 启动服务器
public WebServer Start(string prefixe)
diff --git a/Net461DllTest/Device/SiemensPlcDevice.cs b/Net461DllTest/Device/SiemensPlcDevice.cs
index a0991f8..4c711c6 100644
--- a/Net461DllTest/Device/SiemensPlcDevice.cs
+++ b/Net461DllTest/Device/SiemensPlcDevice.cs
@@ -1,7 +1,8 @@
-using IoTClient.Clients.PLC;
+using IoTClient;
+using IoTClient.Clients.PLC;
+using IoTClient.Enums;
using Net461DllTest.Enums;
using Net461DllTest.Signal;
-using Net461DllTest.Utils;
using Serein.Library.Attributes;
using Serein.Library.NodeFlow.Tool;
using System;
@@ -13,7 +14,7 @@ namespace Net461DllTest.Device
/// 官方文档:如果没有主动Open,则会每次读写操作的时候自动打开自动和关闭连接,这样会使读写效率大大减低。所以建议手动Open和Close。
///
[AutoRegister]
- public class SiemensPlcDevice : ChannelFlowTrigger
+ public class SiemensPlcDevice : ChannelFlowTrigger
{
public SiemensClient Client { get; set; }
@@ -69,4 +70,224 @@ namespace Net461DllTest.Device
}
}
+ ///
+ /// PLC方法
+ ///
+ public static class PlcExtension
+ {
+ public static DataTypeEnum ToDataTypeEnum(this PlcVarInfo varInfo)
+ {
+ Type dataType = varInfo.DataType;
+ DataTypeEnum plcDataType;
+ switch (dataType)
+ {
+ case Type _ when dataType == typeof(string):
+ plcDataType = DataTypeEnum.String;
+ break;
+ case Type _ when dataType == typeof(char):
+ plcDataType = DataTypeEnum.String;
+ break;
+ case Type _ when dataType == typeof(bool):
+ plcDataType = DataTypeEnum.Bool;
+ break;
+ case Type _ when dataType == typeof(float):
+ plcDataType = DataTypeEnum.Float;
+ break;
+ case Type _ when dataType == typeof(double):
+ plcDataType = DataTypeEnum.Double;
+ break;
+ case Type _ when dataType == typeof(byte):
+ plcDataType = DataTypeEnum.Byte;
+ break;
+ case Type _ when dataType == typeof(short):
+ plcDataType = DataTypeEnum.Int16;
+ break;
+ case Type _ when dataType == typeof(ushort):
+ plcDataType = DataTypeEnum.UInt16;
+ break;
+ case Type _ when dataType == typeof(int):
+ plcDataType = DataTypeEnum.Int32;
+ break;
+ case Type _ when dataType == typeof(uint):
+ plcDataType = DataTypeEnum.UInt32;
+ break;
+ case Type _ when dataType == typeof(long):
+ plcDataType = DataTypeEnum.Int64;
+ break;
+ case Type _ when dataType == typeof(ulong):
+ plcDataType = DataTypeEnum.UInt64;
+ break;
+ default:
+ plcDataType = DataTypeEnum.None;
+ break;
+ }
+
+
+ return plcDataType;
+ }
+
+ ///
+ /// 读取设备的值
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static object ReadToPlcValue(this SiemensClient client, PlcVarInfo varInfo)
+ {
+ Type dataType = varInfo.DataType;
+ object resultvalue;
+ if (dataType == typeof(string))
+ {
+ var result = client.ReadString(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(char))
+ {
+ var result = client.ReadString(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(bool))
+ {
+ var result = client.ReadBoolean(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(float))
+ {
+ var result = client.ReadFloat(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(double))
+ {
+ var result = client.ReadDouble(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(byte))
+ {
+ var result = client.ReadByte(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(short))
+ {
+ var result = client.ReadInt16(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(ushort))
+ {
+ var result = client.ReadUInt16(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(int))
+ {
+ var result = client.ReadInt32(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(uint))
+ {
+ var result = client.ReadUInt32(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(long))
+ {
+ var result = client.ReadInt64(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else if (dataType == typeof(ulong))
+ {
+ var result = client.ReadUInt64(varInfo.VarAddress);
+ if (!result.IsSucceed) throw new Exception(result.Err);
+ resultvalue = result.Value;
+ }
+ else
+ {
+ resultvalue = default;
+ }
+ return resultvalue;
+ }
+
+ public static void WriteToPlcValue(this SiemensClient client, PlcVarInfo varInfo, object value)
+ {
+ if (client == null) throw new ArgumentNullException("client");
+ Type dataType = varInfo.DataType;
+ Result result = null;
+ if (dataType == typeof(string))
+ {
+ result = client.Write(varInfo.VarAddress, value.ToString());
+ }
+ else if (dataType == typeof(char))
+ {
+ result = client.Write(varInfo.VarAddress, value.ToString());
+ }
+ else if (dataType == typeof(bool))
+ {
+ var @bool = bool.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @bool);
+ }
+ else if (dataType == typeof(float))
+ {
+ var @float = float.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @float);
+ }
+ else if (dataType == typeof(double))
+ {
+ var @double = double.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @double);
+ }
+ else if (dataType == typeof(byte))
+ {
+ var @byte = byte.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @byte);
+ }
+ else if (dataType == typeof(short))
+ {
+ var @short = short.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @short);
+ }
+ else if (dataType == typeof(ushort))
+ {
+ var @ushort = ushort.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @ushort);
+ }
+ else if (dataType == typeof(int))
+ {
+ var @int = int.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @int);
+ }
+ else if (dataType == typeof(uint))
+ {
+ var @uint = uint.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @uint);
+ }
+ else if (dataType == typeof(long))
+ {
+ var @long = long.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @long);
+ }
+ else if (dataType == typeof(ulong))
+ {
+ var @ulong = ulong.Parse(value.ToString());
+ result = client.Write(varInfo.VarAddress, @ulong);
+ }
+ if (result is null)
+ {
+ throw new Exception($"未定义的数据类型");
+ }
+ if (!result.IsSucceed)
+ {
+ throw new Exception(result.Err);
+ }
+ }
+
+ }
}
diff --git a/Net461DllTest/Enums/PlcVarEnum.cs b/Net461DllTest/Enums/PlcVarEnum.cs
index 8fac389..2ccaaf8 100644
--- a/Net461DllTest/Enums/PlcVarEnum.cs
+++ b/Net461DllTest/Enums/PlcVarEnum.cs
@@ -17,18 +17,35 @@ namespace Net461DllTest.Enums
public enum PlcVarEnum
{
None,
+ ///
+ /// 车位号
+ ///
+ [PlcValue(typeof(short), "V100", VarType.Writable)]
+ SpaceNum,
+
///
/// 上位机指令
///
[PlcValue(typeof(short), "V102", VarType.Writable)]
CmdForPLC,
+ ///
+ /// PLC当前存取车位号
+ ///
+ [PlcValue(typeof(short), "V110", VarType.ReadOnly)]
+ DoingSpaceNum,
+
///
/// 下位机状态
///
[PlcValue(typeof(short), "V112", VarType.ReadOnly)]
PLCState,
+ ///
+ /// 门1正常待机车位号,存车完成地面车位0
+ ///
+ [PlcValue(typeof(short), "V114", VarType.ReadOnly)]
+ Door1CurSpaceNum,
///
/// 门2正常待机车位号,存车完成地面车位0
@@ -73,6 +90,17 @@ namespace Net461DllTest.Enums
[PlcValue(typeof(bool), "V207.4", VarType.ReadOnly)]
IsDoor2ClosedDone,
+ ///
+ /// 通道1是否有车
+ ///
+ [PlcValue(typeof(bool), "V284.7", VarType.ReadOnly)]
+ HasCarInTone1,
+
+ ///
+ /// 通道2是否有车
+ ///
+ [PlcValue(typeof(bool), "V286.7", VarType.ReadOnly)]
+ HasCarInTone2,
///
/// 下位机异常代码
@@ -80,6 +108,12 @@ namespace Net461DllTest.Enums
[PlcValue(typeof(short), "V2", VarType.ReadOnly)]
ErrorCode,
+ ///
+ /// 2层以上的空板是否在待机
+ ///
+ [PlcValue(typeof(bool), "V200.7", VarType.ReadOnly)]
+ IsOver2FlowStanded,
+
///
/// 1号门指示灯
///
diff --git a/Net461DllTest/LogicControl/PlcLogicControl.cs b/Net461DllTest/LogicControl/PlcLogicControl.cs
index 9ed600c..07caa0a 100644
--- a/Net461DllTest/LogicControl/PlcLogicControl.cs
+++ b/Net461DllTest/LogicControl/PlcLogicControl.cs
@@ -29,30 +29,43 @@ namespace Net461DllTest.LogicControl
public PlcLogicControl(SiemensPlcDevice MyPlc)
{
this.MyPlc = MyPlc;
+
+
}
#region 初始化、初始化完成以及退出的事件
[NodeAction(NodeType.Init)] // Init : 初始化事件,流程启动时执行
public void Init(IDynamicContext context)
{
- // // 注册控制器
- context.Env.IOC.Run(router => {
- router.RegisterController(typeof(ApiController));
- });
+ context.Env.IOC.Register();
+ context.Env.IOC.Register();
+
}
[NodeAction(NodeType.Loading)] // Loading 初始化完成已注入依赖项,可以开始逻辑上的操作
public void Loading(IDynamicContext context)
{
- context.Env.IOC.Run((web) =>
- {
- web.Start("http://*:8089/"); // 开启 Web 服务
+ // 注册控制器
+ context.Env.IOC.Run((router, web) => {
+ try
+ {
+ router.RegisterController(typeof(CommandController));
+ web.Start("http://*:8089/"); // 开启 Web 服务
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
});
}
[NodeAction(NodeType.Exit)] // 流程结束时自动执行
public void Exit(IDynamicContext context)
{
+ context.Env.IOC.Run((web) =>
+ {
+ web?.Stop(); // 关闭 Web 服务
+ });
MyPlc.ResetDevice();
MyPlc.CancelAllTasks();
}
@@ -62,7 +75,7 @@ namespace Net461DllTest.LogicControl
#region 触发器节点
[NodeAction(NodeType.Flipflop, "等待信号触发", ReturnType = typeof(int))]
- public async Task WaitTask(OrderSignal order = OrderSignal.Command_1)
+ public async Task WaitTask(CommandSignal order = CommandSignal.Command_1)
{
try
{
@@ -113,7 +126,6 @@ namespace Net461DllTest.LogicControl
return MyPlc;
}
-
[NodeAction(NodeType.Action, "设置PLC状态")]
public SiemensPlcDevice SetState(PlcState state = PlcState.PowerOff)
{
@@ -129,14 +141,12 @@ namespace Net461DllTest.LogicControl
Console.WriteLine($"PLC尚未初始化");
return MyPlc;
}
-
}
- // [BindConvertor(typeof(PlcVarEnum), typeof(PlcVarConvertor))]
[NodeAction(NodeType.Action, "PLC获取变量")]
public object ReadVar(PlcVarEnum plcVarEnum)
{
- var varInfo = Convertor(plcVarEnum);
+ var varInfo = ToVarInfo(plcVarEnum);
var result = MyPlc.Read(varInfo);
Console.WriteLine($"获取变量成功:({varInfo})\t result = {result}");
return result;
@@ -145,7 +155,7 @@ namespace Net461DllTest.LogicControl
[NodeAction(NodeType.Action, "PLC写入变量")]
public SiemensPlcDevice WriteVar2(object value, PlcVarEnum plcVarEnum)
{
- var varInfo = Convertor(plcVarEnum);
+ var varInfo = ToVarInfo(plcVarEnum);
if (MyPlc.State == PlcState.Runing)
{
if (varInfo.IsProtected)
@@ -165,9 +175,12 @@ namespace Net461DllTest.LogicControl
return MyPlc;
}
-
- private readonly Dictionary VarInfoDict;
- public PlcVarInfo Convertor(PlcVarEnum plcVarEnum)
+ ///
+ /// 缓存变量信息
+ ///
+ private readonly Dictionary VarInfoDict = new Dictionary();
+
+ private PlcVarInfo ToVarInfo(PlcVarEnum plcVarEnum)
{
if (VarInfoDict.ContainsKey(plcVarEnum))
{
@@ -187,28 +200,6 @@ namespace Net461DllTest.LogicControl
return plcValue;
}
- ///
- /// 转换器,用于将枚举转为自定义特性中的数据
- ///
- //public class PlcVarConvertor: IEnumConvertor
- //{
- // public PlcVarInfo Convertor(PlcVarEnum plcVarValue)
- // {
- // if (plcVarValue == PlcVarEnum.None)
- // {
- // throw new Exception("非预期枚举值");
- // }
- // var plcValue = EnumHelper.GetBoundValue(plcVarValue, attr => attr.PlcInfo)
- // ?? throw new Exception($"获取变量异常:{plcVarValue},没有标记PlcValueAttribute");
- // if (string.IsNullOrEmpty(plcValue.VarAddress))
- // {
- // throw new Exception($"获取变量异常:{plcVarValue},变量地址为空");
- // }
- // return plcValue;
- // }
-
- //}
-
#endregion
}
}
diff --git a/Net461DllTest/LogicControl/ViewLogicControl.cs b/Net461DllTest/LogicControl/ViewLogicControl.cs
index 031495b..15aa626 100644
--- a/Net461DllTest/LogicControl/ViewLogicControl.cs
+++ b/Net461DllTest/LogicControl/ViewLogicControl.cs
@@ -10,19 +10,23 @@ using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
-namespace Net461DllTest.LogicControl
-{
+namespace Net461DllTest.LogicControl
+{
+
+ ///
+ /// 视图管理
+ ///
[AutoRegister]
public class ViewManagement
{
-
private List