From 1778bd59a022f1dc22b5ad8570b41502b188f70d Mon Sep 17 00:00:00 2001 From: luosheng Date: Tue, 28 Mar 2023 19:04:50 +0800 Subject: [PATCH] Add an reflection method in machine --- .../IUtilityMethodTime.cs | 3 -- .../ModbusUtilityTime.cs | 3 -- .../Modbus.Net.Modbus/ModbusProtocol.cs | 2 +- Modbus.Net/Modbus.Net/Interface/IMachine.cs | 2 +- .../Interface/IMachineReflectionCall.cs | 29 ++++++++++++ .../Modbus.Net/Job/MachineJobScheduler.cs | 21 ++++++--- Modbus.Net/Modbus.Net/Machine/BaseMachine.cs | 45 ++++++++++++++----- Tests/Modbus.Net.Tests/MachineMethodTest.cs | 4 +- 8 files changed, 82 insertions(+), 27 deletions(-) create mode 100644 Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs diff --git a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/IUtilityMethodTime.cs b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/IUtilityMethodTime.cs index 0e57309..ff2de27 100644 --- a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/IUtilityMethodTime.cs +++ b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/IUtilityMethodTime.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Modbus.Net.Modbus.SelfDefinedSample diff --git a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/ModbusUtilityTime.cs b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/ModbusUtilityTime.cs index 8aa0b1c..2165d46 100644 --- a/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/ModbusUtilityTime.cs +++ b/Modbus.Net/Modbus.Net.Modbus.SelfDefinedSample/ModbusUtilityTime.cs @@ -1,8 +1,5 @@ using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Modbus.Net.Modbus.SelfDefinedSample diff --git a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs index e37d4e5..1adefe1 100644 --- a/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs +++ b/Modbus.Net/Modbus.Net.Modbus/ModbusProtocol.cs @@ -28,7 +28,7 @@ namespace Modbus.Net.Modbus /// 读输入寄存器 /// ReadInputRegister = 4, - + /// /// 写单个线圈 /// diff --git a/Modbus.Net/Modbus.Net/Interface/IMachine.cs b/Modbus.Net/Modbus.Net/Interface/IMachine.cs index a1cd92e..cdfb9db 100644 --- a/Modbus.Net/Modbus.Net/Interface/IMachine.cs +++ b/Modbus.Net/Modbus.Net/Interface/IMachine.cs @@ -13,7 +13,7 @@ namespace Modbus.Net /// 设备的抽象 /// /// - public interface IMachine : IMachineProperty, IMachineMethodData where TKey : IEquatable + public interface IMachine : IMachineProperty, IMachineMethodData, IMachineReflectionCall where TKey : IEquatable { } } diff --git a/Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs b/Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs new file mode 100644 index 0000000..bafc560 --- /dev/null +++ b/Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; + +namespace Modbus.Net +{ + /// + /// 设备的反射调用接口 + /// + public interface IMachineReflectionCall + { + /// + /// 反射方式调用获取方法 + /// + /// 要返回的数据类型 + /// 方法名 + /// 参数 + /// 返回的数据 + Task> InvokeGet(string functionName, object[] parameters); + + /// + /// 反射方式调用设置方法 + /// + /// 要设置的数据类型 + /// 方法名 + /// 参数 + /// 要设置的数据 + /// 设置是否成功 + Task> InvokeSet(string functionName, object[] parameters, T datas); + } +} diff --git a/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs b/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs index 5712fdf..2843718 100644 --- a/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs +++ b/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs @@ -145,9 +145,10 @@ namespace Modbus.Net /// 任务ID,每个触发器唯一 /// 要获取数据的设备实例 /// 获取数据的方式 + /// 调用函数的名称 /// /// - public async Task From(string queryId, IMachineMethodData machine, MachineDataType machineDataType) + public async Task From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType, string callFunction = "Datas") { JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); @@ -158,6 +159,7 @@ namespace Modbus.Net job.JobDataMap.Put("DataType", machineDataType); job.JobDataMap.Put("Machine", machine); + job.JobDataMap.Put("Function", callFunction); if (_parentJobKey != null) { @@ -351,9 +353,10 @@ namespace Modbus.Net /// /// 任务ID,每个触发器唯一 /// 写入数据的设备实例 + /// 调用函数的名称 /// /// - public async Task To(string queryId, IMachineMethodData machine) + public async Task To(string queryId, IMachineReflectionCall machine, string callFunction = "Datas") { JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name); @@ -363,6 +366,7 @@ namespace Modbus.Net .Build(); job.JobDataMap.Put("Machine", machine); + job.JobDataMap.Put("Function", callFunction); var listener = _scheduler.ListenerManager.GetJobListener("Modbus.Net.DataQuery.Chain." + _trigger.Key.Name) as JobChainingJobListenerWithDataMap; if (listener == null) throw new NullReferenceException("Listener " + "Modbus.Net.DataQuery.Chain." + _trigger.Key.Name + " is null"); @@ -379,10 +383,11 @@ namespace Modbus.Net /// 任务ID,每个触发器唯一 /// 要获取数据的设备实例 /// 获取数据的方式 + /// 调用函数的名称 /// - public async Task From(string queryId, IMachineMethodData machine, MachineDataType machineDataType) + public async Task From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType, string callFunction = "Datas") { - return await new MachineGetJobScheduler(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType); + return await new MachineGetJobScheduler(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType, callFunction); } /// @@ -476,9 +481,11 @@ namespace Modbus.Net { object machine; object machineDataType; + object callFunction; context.JobDetail.JobDataMap.TryGetValue("Machine", out machine); context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType); - var values = await (machine as IMachineMethodData)!.GetDatasAsync((MachineDataType)machineDataType); + context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction); + var values = await (machine as IMachineReflectionCall)!.InvokeGet>((string)callFunction, new object[] { (MachineDataType)machineDataType }); context.JobDetail.JobDataMap.Put("Value", values); await context.Scheduler.AddJob(context.JobDetail, true, false); @@ -522,10 +529,12 @@ namespace Modbus.Net object machineDataType; object values; object valuesSet; + object callFunction; context.JobDetail.JobDataMap.TryGetValue("Machine", out machine); context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType); context.JobDetail.JobDataMap.TryGetValue("Value", out values); context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet); + context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction); if (valuesSet == null && values != null) valuesSet = ((ReturnStruct>)values).Datas.MapGetValuesToSetValues(); @@ -534,7 +543,7 @@ namespace Modbus.Net context.JobDetail.JobDataMap.Put("Success", false); return; } - var success = await (machine as IMachineMethodData)!.SetDatasAsync((MachineDataType)machineDataType, (Dictionary)valuesSet); + var success = await (machine as IMachineReflectionCall)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary)valuesSet); context.JobDetail.JobDataMap.Put("Success", success); } diff --git a/Modbus.Net/Modbus.Net/Machine/BaseMachine.cs b/Modbus.Net/Modbus.Net/Machine/BaseMachine.cs index dc656a1..204fe85 100644 --- a/Modbus.Net/Modbus.Net/Machine/BaseMachine.cs +++ b/Modbus.Net/Modbus.Net/Machine/BaseMachine.cs @@ -76,7 +76,7 @@ namespace Modbus.Net /// /// 设备的Id类型 /// 设备中使用的AddressUnit的Id类型 - public abstract class BaseMachine : IMachine + public abstract class BaseMachine : IMachine, IMachineReflectionCall where TKey : IEquatable where TUnitKey : IEquatable { @@ -665,6 +665,39 @@ namespace Modbus.Net return null; } + /// + /// 获取Utility的执行方法 + /// + /// Utility实现的接口名称 + /// + public TUtilityMethod GetUtilityMethods() where TUtilityMethod : class, IUtilityMethod + { + return BaseUtility as TUtilityMethod; + } + + /// + public async Task> InvokeGet(string functionName, object[] parameters) + { + var machineMethodType = GetType(); + var machineMethod = this as IMachineMethod; + var machineSetMethod = machineMethodType.GetMethod("Get" + functionName + "Async"); + var ans = machineSetMethod.Invoke(machineMethod, parameters); + return await (Task>)ans; + } + + /// + public async Task> InvokeSet(string functionName, object[] parameters, T datas) + { + var machineMethodType = GetType(); + var machineMethod = this as IMachineMethod; + var machineSetMethod = machineMethodType.GetMethod("Set" + functionName + "Async"); + object[] allParams = new object[parameters.Length + 1]; + Array.Copy(parameters, allParams, parameters.Length); + allParams[parameters.Length] = datas; + var ans = machineSetMethod.Invoke(machineMethod, allParams); + return await (Task>)ans; + } + /// /// 连接设备 /// @@ -709,16 +742,6 @@ namespace Modbus.Net return null; } } - - /// - /// 获取Utility - /// - /// Utility实现的接口名称 - /// - public TUtilityMethod GetUtility() where TUtilityMethod : class, IUtilityMethod - { - return BaseUtility as TUtilityMethod; - } } internal class BaseMachineEqualityComparer : IEqualityComparer> diff --git a/Tests/Modbus.Net.Tests/MachineMethodTest.cs b/Tests/Modbus.Net.Tests/MachineMethodTest.cs index 641555b..491b617 100644 --- a/Tests/Modbus.Net.Tests/MachineMethodTest.cs +++ b/Tests/Modbus.Net.Tests/MachineMethodTest.cs @@ -11,7 +11,7 @@ namespace Modbus.Net.Tests public void GetUtility() { BaseMachine baseMachine = new ModbusMachine(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0); - var utility = baseMachine.GetUtility(); + var utility = baseMachine.GetUtilityMethods(); var methods = utility.GetType().GetRuntimeMethods(); Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetDataAsync") != null, true); Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "SetDataAsync") != null, true); @@ -22,7 +22,7 @@ namespace Modbus.Net.Tests public async Task InvokeUtility() { BaseMachine baseMachine = new ModbusMachine(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0); - var success = await baseMachine.BaseUtility.GetUtilityMethods().SetDatasAsync("4X 1", new object[] {(byte)11}); + var success = await baseMachine.BaseUtility.GetUtilityMethods().SetDatasAsync("4X 1", new object[] { (byte)11 }); Assert.AreEqual(success, true); var datas = await baseMachine.BaseUtility.GetUtilityMethods().GetDatasAsync("4X 1", 1); Assert.AreEqual(datas.Datas[0], 11);