Add an reflection method in machine
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Modbus.Net.Modbus.SelfDefinedSample
|
namespace Modbus.Net.Modbus.SelfDefinedSample
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Modbus.Net.Modbus.SelfDefinedSample
|
namespace Modbus.Net.Modbus.SelfDefinedSample
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Modbus.Net
|
|||||||
/// 设备的抽象
|
/// 设备的抽象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TKey"></typeparam>
|
/// <typeparam name="TKey"></typeparam>
|
||||||
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData where TKey : IEquatable<TKey>
|
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodData, IMachineReflectionCall where TKey : IEquatable<TKey>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs
Normal file
29
Modbus.Net/Modbus.Net/Interface/IMachineReflectionCall.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Modbus.Net
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备的反射调用接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IMachineReflectionCall
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 反射方式调用获取方法
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要返回的数据类型</typeparam>
|
||||||
|
/// <param name="functionName">方法名</param>
|
||||||
|
/// <param name="parameters">参数</param>
|
||||||
|
/// <returns>返回的数据</returns>
|
||||||
|
Task<ReturnStruct<T>> InvokeGet<T>(string functionName, object[] parameters);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反射方式调用设置方法
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要设置的数据类型</typeparam>
|
||||||
|
/// <param name="functionName">方法名</param>
|
||||||
|
/// <param name="parameters">参数</param>
|
||||||
|
/// <param name="datas">要设置的数据</param>
|
||||||
|
/// <returns>设置是否成功</returns>
|
||||||
|
Task<ReturnStruct<bool>> InvokeSet<T>(string functionName, object[] parameters, T datas);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -145,9 +145,10 @@ namespace Modbus.Net
|
|||||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||||
/// <param name="machine">要获取数据的设备实例</param>
|
/// <param name="machine">要获取数据的设备实例</param>
|
||||||
/// <param name="machineDataType">获取数据的方式</param>
|
/// <param name="machineDataType">获取数据的方式</param>
|
||||||
|
/// <param name="callFunction">调用函数的名称</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="NullReferenceException"></exception>
|
/// <exception cref="NullReferenceException"></exception>
|
||||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineMethodData machine, MachineDataType machineDataType)
|
public async Task<MachineQueryJobScheduler> 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);
|
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("DataType", machineDataType);
|
||||||
job.JobDataMap.Put("Machine", machine);
|
job.JobDataMap.Put("Machine", machine);
|
||||||
|
job.JobDataMap.Put("Function", callFunction);
|
||||||
|
|
||||||
if (_parentJobKey != null)
|
if (_parentJobKey != null)
|
||||||
{
|
{
|
||||||
@@ -351,9 +353,10 @@ namespace Modbus.Net
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||||
/// <param name="machine">写入数据的设备实例</param>
|
/// <param name="machine">写入数据的设备实例</param>
|
||||||
|
/// <param name="callFunction">调用函数的名称</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="NullReferenceException"></exception>
|
/// <exception cref="NullReferenceException"></exception>
|
||||||
public async Task<MachineDealJobScheduler> To(string queryId, IMachineMethodData machine)
|
public async Task<MachineDealJobScheduler> To(string queryId, IMachineReflectionCall machine, string callFunction = "Datas")
|
||||||
{
|
{
|
||||||
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
|
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
|
||||||
|
|
||||||
@@ -363,6 +366,7 @@ namespace Modbus.Net
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
job.JobDataMap.Put("Machine", machine);
|
job.JobDataMap.Put("Machine", machine);
|
||||||
|
job.JobDataMap.Put("Function", callFunction);
|
||||||
|
|
||||||
var listener = _scheduler.ListenerManager.GetJobListener("Modbus.Net.DataQuery.Chain." + _trigger.Key.Name) as JobChainingJobListenerWithDataMap;
|
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");
|
if (listener == null) throw new NullReferenceException("Listener " + "Modbus.Net.DataQuery.Chain." + _trigger.Key.Name + " is null");
|
||||||
@@ -379,10 +383,11 @@ namespace Modbus.Net
|
|||||||
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
/// <param name="queryId">任务ID,每个触发器唯一</param>
|
||||||
/// <param name="machine">要获取数据的设备实例</param>
|
/// <param name="machine">要获取数据的设备实例</param>
|
||||||
/// <param name="machineDataType">获取数据的方式</param>
|
/// <param name="machineDataType">获取数据的方式</param>
|
||||||
|
/// <param name="callFunction">调用函数的名称</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<MachineQueryJobScheduler> From(string queryId, IMachineMethodData machine, MachineDataType machineDataType)
|
public async Task<MachineQueryJobScheduler> 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -476,9 +481,11 @@ namespace Modbus.Net
|
|||||||
{
|
{
|
||||||
object machine;
|
object machine;
|
||||||
object machineDataType;
|
object machineDataType;
|
||||||
|
object callFunction;
|
||||||
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
||||||
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
|
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<Dictionary<string, ReturnUnit>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
|
||||||
|
|
||||||
context.JobDetail.JobDataMap.Put("Value", values);
|
context.JobDetail.JobDataMap.Put("Value", values);
|
||||||
await context.Scheduler.AddJob(context.JobDetail, true, false);
|
await context.Scheduler.AddJob(context.JobDetail, true, false);
|
||||||
@@ -522,10 +529,12 @@ namespace Modbus.Net
|
|||||||
object machineDataType;
|
object machineDataType;
|
||||||
object values;
|
object values;
|
||||||
object valuesSet;
|
object valuesSet;
|
||||||
|
object callFunction;
|
||||||
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
|
||||||
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
|
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
|
||||||
context.JobDetail.JobDataMap.TryGetValue("Value", out values);
|
context.JobDetail.JobDataMap.TryGetValue("Value", out values);
|
||||||
context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet);
|
context.JobDetail.JobDataMap.TryGetValue("SetValue", out valuesSet);
|
||||||
|
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
|
||||||
if (valuesSet == null && values != null)
|
if (valuesSet == null && values != null)
|
||||||
valuesSet = ((ReturnStruct<Dictionary<string, ReturnUnit>>)values).Datas.MapGetValuesToSetValues();
|
valuesSet = ((ReturnStruct<Dictionary<string, ReturnUnit>>)values).Datas.MapGetValuesToSetValues();
|
||||||
|
|
||||||
@@ -534,7 +543,7 @@ namespace Modbus.Net
|
|||||||
context.JobDetail.JobDataMap.Put("Success", false);
|
context.JobDetail.JobDataMap.Put("Success", false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var success = await (machine as IMachineMethodData)!.SetDatasAsync((MachineDataType)machineDataType, (Dictionary<string, double>)valuesSet);
|
var success = await (machine as IMachineReflectionCall)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary<string, double>)valuesSet);
|
||||||
|
|
||||||
context.JobDetail.JobDataMap.Put("Success", success);
|
context.JobDetail.JobDataMap.Put("Success", success);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace Modbus.Net
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
/// <typeparam name="TKey">设备的Id类型</typeparam>
|
||||||
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
|
||||||
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>
|
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>, IMachineReflectionCall
|
||||||
where TKey : IEquatable<TKey>
|
where TKey : IEquatable<TKey>
|
||||||
where TUnitKey : IEquatable<TUnitKey>
|
where TUnitKey : IEquatable<TUnitKey>
|
||||||
{
|
{
|
||||||
@@ -665,6 +665,39 @@ namespace Modbus.Net
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取Utility的执行方法
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TUtilityMethod GetUtilityMethods<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
|
||||||
|
{
|
||||||
|
return BaseUtility as TUtilityMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<ReturnStruct<T>> InvokeGet<T>(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<ReturnStruct<T>>)ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task<ReturnStruct<bool>> InvokeSet<T>(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<ReturnStruct<bool>>)ans;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 连接设备
|
/// 连接设备
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -709,16 +742,6 @@ namespace Modbus.Net
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Utility
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TUtilityMethod">Utility实现的接口名称</typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public TUtilityMethod GetUtility<TUtilityMethod>() where TUtilityMethod : class, IUtilityMethod
|
|
||||||
{
|
|
||||||
return BaseUtility as TUtilityMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
|
internal class BaseMachineEqualityComparer<TKey> : IEqualityComparer<IMachineProperty<TKey>>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Modbus.Net.Tests
|
|||||||
public void GetUtility()
|
public void GetUtility()
|
||||||
{
|
{
|
||||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
|
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
|
||||||
var utility = baseMachine.GetUtility<IUtilityMethodData>();
|
var utility = baseMachine.GetUtilityMethods<IUtilityMethodData>();
|
||||||
var methods = utility.GetType().GetRuntimeMethods();
|
var methods = utility.GetType().GetRuntimeMethods();
|
||||||
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetDataAsync") != null, true);
|
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetDataAsync") != null, true);
|
||||||
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "SetDataAsync") != null, true);
|
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "SetDataAsync") != null, true);
|
||||||
|
|||||||
Reference in New Issue
Block a user