move IMachineReflectionCall to extend method

This commit is contained in:
luosheng
2023-04-11 14:55:30 +08:00
parent ef55c5e5e5
commit 7ae3b88eaa
10 changed files with 115 additions and 73 deletions

View File

@@ -6,7 +6,7 @@ namespace Modbus.Net
/// 设备的抽象
/// </summary>
/// <typeparam name="TKey"></typeparam>
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodDatas, IMachineReflectionCall where TKey : IEquatable<TKey>
public interface IMachine<TKey> : IMachineProperty<TKey>, IMachineMethodDatas where TKey : IEquatable<TKey>
{
}
}

View File

@@ -1,29 +0,0 @@
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);
}
}

View File

@@ -3,7 +3,7 @@
/// <summary>
/// Api入口的抽象
/// </summary>
public interface IUtility : IUtilityProperty, IUtilityMethodData
public interface IUtility : IUtilityProperty, IUtilityMethodDatas
{
}
}

View File

@@ -14,7 +14,7 @@ namespace Modbus.Net
/// <summary>
/// Utility的数据读写接口
/// </summary>
public interface IUtilityMethodData : IUtilityMethod
public interface IUtilityMethodDatas : IUtilityMethod
{
/// <summary>
/// 获取数据

View File

@@ -140,7 +140,7 @@ namespace Modbus.Net
/// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType)
public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineMethod machine, MachineDataType machineDataType)
{
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
@@ -314,7 +314,7 @@ namespace Modbus.Net
/// <param name="machine">写入数据的设备实例</param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public async Task<MachineDealJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> To(string queryId, IMachineReflectionCall machine)
public async Task<MachineDealJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> To(string queryId, IMachineMethod machine)
{
JobKey jobKey = JobKey.Create("Modbus.Net.DataQuery.Job." + queryId, "Modbus.Net.DataQuery.Group." + _trigger.Key.Name);
@@ -347,7 +347,7 @@ namespace Modbus.Net
/// <param name="machine">要获取数据的设备实例</param>
/// <param name="machineDataType">获取数据的方式</param>
/// <returns></returns>
public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineReflectionCall machine, MachineDataType machineDataType)
public async Task<MachineQueryJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>> From(string queryId, IMachineMethod machine, MachineDataType machineDataType)
{
return await new MachineGetJobScheduler<TMachineMethod, TMachineKey, TReturnUnit>(_scheduler, _trigger, _parentJobKey).From(queryId, machine, machineDataType);
}
@@ -433,7 +433,7 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.TryGetValue("Machine", out machine);
context.JobDetail.JobDataMap.TryGetValue("DataType", out machineDataType);
context.JobDetail.JobDataMap.TryGetValue("Function", out callFunction);
var values = await (machine as IMachineReflectionCall)!.InvokeGet<Dictionary<string, ReturnUnit<TReturnUnit>>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
var values = await (machine as IMachineMethod)!.InvokeGet<Dictionary<string, ReturnUnit<TReturnUnit>>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
context.JobDetail.JobDataMap.Put("Value", values);
await context.Scheduler.AddJob(context.JobDetail, true, false);
@@ -492,7 +492,7 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.Put("Success", false);
return;
}
var success = await (machine as IMachineReflectionCall)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary<string, double>)valuesSet);
var success = await (machine as IMachineMethod)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary<string, double>)valuesSet);
context.JobDetail.JobDataMap.Put("Success", success);
}

View File

@@ -37,7 +37,7 @@ namespace Modbus.Net
/// </summary>
/// <typeparam name="TKey">设备的Id类型</typeparam>
/// <typeparam name="TUnitKey">设备中使用的AddressUnit的Id类型</typeparam>
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>, IMachineReflectionCall
public abstract class BaseMachine<TKey, TUnitKey> : IMachine<TKey>
where TKey : IEquatable<TKey>
where TUnitKey : IEquatable<TUnitKey>
{
@@ -187,7 +187,7 @@ namespace Modbus.Net
//获取数据
var datas =
await
BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync(
BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync(
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address,
communicateAddress.SubAddress),
(int)
@@ -433,7 +433,7 @@ namespace Modbus.Net
communicateAddress.Address);
var datasReturn =
await BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync(
await BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync(
AddressFormater.FormatAddress(communicateAddress.Area, communicateAddress.Address, 0),
(int)
Math.Ceiling(communicateAddress.GetCount *
@@ -545,7 +545,7 @@ namespace Modbus.Net
}
//写入数据
await
BaseUtility.GetUtilityMethods<IUtilityMethodData>().SetDatasAsync(addressStart,
BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().SetDatasAsync(addressStart,
valueHelper.ByteArrayToObjectArray(datas.Datas,
new KeyValuePair<Type, int>(communicateAddress.DataType, communicateAddress.GetCount)));
}
@@ -636,29 +636,6 @@ namespace Modbus.Net
return BaseUtility as TUtilityMethod;
}
/// <inheritdoc />
public 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 (Task<ReturnStruct<T>>)ans;
}
/// <inheritdoc />
public 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 (Task<ReturnStruct<bool>>)ans;
}
/// <summary>
/// 连接设备
/// </summary>

View File

@@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// 设备的反射调用接口
/// </summary>
public static class MachineMethodReflectionCall
{
/// <summary>
/// 反射方式调用获取方法
/// </summary>
/// <typeparam name="T">要返回的数据类型</typeparam>
/// <param name="machineMethod">设备方法组</param>
/// <param name="functionName">方法名</param>
/// <param name="parameters">参数</param>
/// <returns>返回的数据</returns>
public static Task<ReturnStruct<T>> InvokeGet<T>(this IMachineMethod machineMethod, string functionName, object[] parameters)
{
var machineMethodType = machineMethod.GetType();
var machineGetMethod = machineMethodType.GetMethod("Get" + functionName + "Async");
var ans = machineGetMethod.Invoke(machineMethod, parameters);
return (Task<ReturnStruct<T>>)ans;
}
/// <summary>
/// 反射方式调用设置方法
/// </summary>
/// <typeparam name="T">要设置的数据类型</typeparam>
/// <param name="machineMethod">设备方法组</param>
/// <param name="functionName">方法名</param>
/// <param name="parameters">参数</param>
/// <param name="datas">要设置的数据</param>
/// <returns>设置是否成功</returns>
public static Task<ReturnStruct<bool>> InvokeSet<T>(this IMachineMethod machineMethod, string functionName, object[] parameters, T datas)
{
var machineMethodType = machineMethod.GetType();
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 (Task<ReturnStruct<bool>>)ans;
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
namespace Modbus.Net
{
/// <summary>
/// 设备的反射调用接口
/// </summary>
public static class UtilityMethodReflectionCall
{
/// <summary>
/// 反射方式调用获取方法
/// </summary>
/// <typeparam name="T">要返回的数据类型</typeparam>
/// <param name="utilityMethod">方法组</param>
/// <param name="functionName">方法名</param>
/// <param name="parameters">参数</param>
/// <returns>返回的数据</returns>
public static Task<ReturnStruct<T>> InvokeGet<T>(this IUtilityMethod utilityMethod, string functionName, object[] parameters)
{
var utilityMethodType = utilityMethod.GetType();
var utilityGetMethod = utilityMethodType.GetMethod("Get" + functionName + "Async");
var ans = utilityGetMethod.Invoke(utilityMethod, parameters);
return (Task<ReturnStruct<T>>)ans;
}
/// <summary>
/// 反射方式调用设置方法
/// </summary>
/// <typeparam name="T">要设置的数据类型</typeparam>
/// <param name="utilityMethod">方法组</param>
/// <param name="functionName">方法名</param>
/// <param name="parameters">参数</param>
/// <param name="datas">要设置的数据</param>
/// <returns>设置是否成功</returns>
public static Task<ReturnStruct<bool>> InvokeSet<T>(this IUtilityMethod utilityMethod, string functionName, object[] parameters, T datas)
{
var utilityMethodType = utilityMethod.GetType();
var utilitySetMethod = utilityMethodType.GetMethod("Set" + functionName + "Async");
object[] allParams = new object[parameters.Length + 1];
Array.Copy(parameters, allParams, parameters.Length);
allParams[parameters.Length] = datas;
var ans = utilitySetMethod.Invoke(utilityMethod, allParams);
return (Task<ReturnStruct<bool>>)ans;
}
}
}

View File

@@ -11,7 +11,7 @@ namespace Modbus.Net.Tests
public void GetUtility()
{
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
var utility = baseMachine.GetUtilityMethods<IUtilityMethodData>();
var utility = baseMachine.GetUtilityMethods<IUtilityMethodDatas>();
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,9 +22,9 @@ namespace Modbus.Net.Tests
public async Task InvokeUtility()
{
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, "192.168.3.12", null, true, 2, 0);
var success = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().SetDatasAsync("4X 1", new object[] { (byte)11 });
var success = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().SetDatasAsync("4X 1", new object[] { (byte)11 });
Assert.AreEqual(success, true);
var datas = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync("4X 1", 1);
var datas = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync("4X 1", 1);
Assert.AreEqual(datas.Datas[0], 11);
baseMachine.Disconnect();
}

View File

@@ -292,18 +292,18 @@ namespace Modbus.Net.Tests
await _modbusTcpMachine!.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("4X 1", dic1["4X 1"]);
await _modbusAsciiMachine!.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("4X 1", dic1["4X 1"]);
await _modbusRtuMachine!.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("4X 1", dic1["4X 1"]);
var ans = await _modbusTcpMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<ushort>("4X 1", 1);
var ans2 = await _modbusRtuMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<ushort>("4X 1", 1);
var ans3 = await _modbusAsciiMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<ushort>("4X 1", 1);
var ans = await _modbusTcpMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<ushort>("4X 1", 1);
var ans2 = await _modbusRtuMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<ushort>("4X 1", 1);
var ans3 = await _modbusAsciiMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<ushort>("4X 1", 1);
Assert.AreEqual(ans.Datas[0], dic1["4X 1"]);
Assert.AreEqual(ans2.Datas[0], dic1["4X 1"]);
Assert.AreEqual(ans3.Datas[0], dic1["4X 1"]);
await _modbusTcpMachine.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("0X 1", dic2["0X 1"] >= 1);
await _modbusAsciiMachine.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("0X 1", dic2["0X 1"] >= 1);
await _modbusRtuMachine.BaseUtility.GetUtilityMethods<IUtilityMethodWriteSingleCoil>().SetSingleCoilAsync("0X 1", dic2["0X 1"] >= 1);
var ans21 = await _modbusTcpMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<bool>("0X 1", 1);
var ans22 = await _modbusRtuMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<bool>("0X 1", 1);
var ans23 = await _modbusAsciiMachine.BaseUtility.GetUtilityMethods<IUtilityMethodData>().GetDatasAsync<bool>("0X 1", 1);
var ans21 = await _modbusTcpMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<bool>("0X 1", 1);
var ans22 = await _modbusRtuMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<bool>("0X 1", 1);
var ans23 = await _modbusAsciiMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().GetDatasAsync<bool>("0X 1", 1);
Assert.AreEqual(ans21.Datas[0] ? 1 : 0, dic2["0X 1"]);
Assert.AreEqual(ans22.Datas[0] ? 1 : 0, dic2["0X 1"]);
Assert.AreEqual(ans23.Datas[0] ? 1 : 0, dic2["0X 1"]);