diff --git a/Modbus.Net/Modbus.Net/Async/AsyncHelper.cs b/Modbus.Net/Modbus.Net/Helper/AsyncHelper.cs
similarity index 100%
rename from Modbus.Net/Modbus.Net/Async/AsyncHelper.cs
rename to Modbus.Net/Modbus.Net/Helper/AsyncHelper.cs
diff --git a/Modbus.Net/Modbus.Net/Helper/ExtendedMethodHelper.cs b/Modbus.Net/Modbus.Net/Helper/ExtendedMethodHelper.cs
new file mode 100644
index 0000000..9f1beed
--- /dev/null
+++ b/Modbus.Net/Modbus.Net/Helper/ExtendedMethodHelper.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace Modbus.Net
+{
+ ///
+ /// 获取扩展方法的类
+ ///
+ public static class ExtendedMethodHelper
+ {
+ ///
+ /// 获取程序集中的所有扩展方法
+ ///
+ /// 扩展方法的第一个参数类即扩展类
+ /// 程序集
+ ///
+ public static IEnumerable GetExtensionMethods(this Type extendedType, Assembly assembly)
+ {
+ var query = from type in assembly.GetTypes()
+ where type.IsSealed && !type.IsGenericType && !type.IsNested
+ from method in type.GetMethods(BindingFlags.Static
+ | BindingFlags.Public | BindingFlags.NonPublic)
+ where method.IsDefined(typeof(ExtensionAttribute), false)
+ where method.GetParameters()[0].ParameterType == extendedType
+ select method;
+ return query.ToList();
+ }
+ }
+}
diff --git a/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs b/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs
index ef4032b..4e4ef05 100644
--- a/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs
+++ b/Modbus.Net/Modbus.Net/Job/MachineJobScheduler.cs
@@ -3,6 +3,8 @@ using Quartz.Impl;
using Quartz.Impl.Matchers;
using System;
using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
using System.Threading.Tasks;
namespace Modbus.Net
@@ -149,14 +151,10 @@ namespace Modbus.Net
.StoreDurably(true)
.Build();
- string methodName = typeof(TMachineMethod).Name;
- if (methodName.Substring(0, 14) != "IMachineMethod")
- {
- throw new FormatException("IMachineMethod Name not match format exception");
- }
+ Type methodType = typeof(TMachineMethod);
job.JobDataMap.Put("DataType", machineDataType);
job.JobDataMap.Put("Machine", machine);
- job.JobDataMap.Put("Function", methodName.Remove(0, 14));
+ job.JobDataMap.Put("MethodType", methodType);
if (_parentJobKey != null)
{
@@ -323,13 +321,9 @@ namespace Modbus.Net
.StoreDurably(true)
.Build();
- string methodName = typeof(TMachineMethod).Name;
- if (methodName.Substring(0, 14) != "IMachineMethod")
- {
- throw new FormatException("IMachineMethod Name not match format exception");
- }
+ Type methodType = typeof(TMachineMethod);
job.JobDataMap.Put("Machine", machine);
- job.JobDataMap.Put("Function", methodName.Remove(0, 14));
+ job.JobDataMap.Put("MethodType", methodType);
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");
@@ -366,7 +360,7 @@ namespace Modbus.Net
/// 处理写返回任务
///
public sealed class MachineDealJobScheduler where TMachineKey : IEquatable where TReturnUnit : struct where TMachineMethod : class, IMachineMethod
- {
+ {
private IScheduler _scheduler;
private ITrigger _trigger;
@@ -429,11 +423,13 @@ namespace Modbus.Net
{
object machine;
object machineDataType;
- object callFunction;
+ object methodType;
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 IMachineMethod)!.InvokeGet>>((string)callFunction, new object[] { (MachineDataType)machineDataType });
+ context.JobDetail.JobDataMap.TryGetValue("MethodType", out methodType);
+
+ MethodInfo invokeGetGenericMethod = typeof(IMachineMethod).GetExtensionMethods(GetType().Assembly).First(p => p.Name == "InvokeGet").MakeGenericMethod((Type)methodType, typeof(Dictionary>));
+ var values = await (Task>>>)invokeGetGenericMethod.Invoke(machine, new object[] { machine, new object[] { (MachineDataType)machineDataType } });
context.JobDetail.JobDataMap.Put("Value", values);
await context.Scheduler.AddJob(context.JobDetail, true, false);
@@ -476,12 +472,12 @@ namespace Modbus.Net
object machineDataType;
object values;
object valuesSet;
- object callFunction;
+ object methodType;
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);
+ context.JobDetail.JobDataMap.TryGetValue("MethodType", out methodType);
if (valuesSet == null && values != null)
{
valuesSet = ((ReturnStruct>>)values).Datas.MapGetValuesToSetValues();
@@ -492,7 +488,8 @@ namespace Modbus.Net
context.JobDetail.JobDataMap.Put("Success", false);
return;
}
- var success = await (machine as IMachineMethod)!.InvokeSet((string)callFunction, new object[] { (MachineDataType)machineDataType }, (Dictionary)valuesSet);
+ MethodInfo invokeGetGenericMethod = typeof(IMachineMethod).GetExtensionMethods(GetType().Assembly).First(p => p.Name == "InvokeSet").MakeGenericMethod((Type)methodType, typeof(Dictionary));
+ var success = await (Task>)invokeGetGenericMethod.Invoke(machine, new object[] { machine, new object[] { (MachineDataType)machineDataType }, (Dictionary)valuesSet });
context.JobDetail.JobDataMap.Put("Success", success);
}
diff --git a/Modbus.Net/Modbus.Net/Machine/MachineMethodReflectionCall.cs b/Modbus.Net/Modbus.Net/Machine/MachineMethodReflectionCall.cs
index f7a77b3..be24917 100644
--- a/Modbus.Net/Modbus.Net/Machine/MachineMethodReflectionCall.cs
+++ b/Modbus.Net/Modbus.Net/Machine/MachineMethodReflectionCall.cs
@@ -3,11 +3,30 @@ using System.Threading.Tasks;
namespace Modbus.Net
{
+
///
/// 设备的反射调用接口
///
public static class MachineMethodReflectionCall
{
+ ///
+ /// 反射方式调用获取方法
+ ///
+ /// 方法组的类型
+ /// 要返回的数据类型
+ /// 方法组
+ /// 参数
+ /// 返回的数据
+ public static Task> InvokeGet(this IMachineMethod machineMethod, object[] parameters) where TMachineMethod : IMachineMethod
+ {
+ if (typeof(TMachineMethod).Name[..14] != "IMachineMethod")
+ {
+ throw new NotSupportedException("IMachineMethod type name not begin with IMachineMethod");
+ }
+ var functionName = "Get" + typeof(TMachineMethod).Name[14..] + "Async";
+ return InvokeGet(machineMethod, functionName, parameters);
+ }
+
///
/// 反射方式调用获取方法
///
@@ -19,11 +38,30 @@ namespace Modbus.Net
public static Task> InvokeGet(this IMachineMethod machineMethod, string functionName, object[] parameters)
{
var machineMethodType = machineMethod.GetType();
- var machineGetMethod = machineMethodType.GetMethod("Get" + functionName + "Async");
+ var machineGetMethod = machineMethodType.GetMethod(functionName);
var ans = machineGetMethod.Invoke(machineMethod, parameters);
return (Task>)ans;
}
+ ///
+ /// 反射方式调用设置方法
+ ///
+ /// 方法组的类型
+ /// 要设置的数据类型
+ /// 方法组
+ /// 参数
+ /// 要设置的数据
+ /// 设置是否成功
+ public static Task> InvokeSet(this IMachineMethod machineMethod, object[] parameters, T datas) where TMachineMethod : IMachineMethod
+ {
+ if (typeof(TMachineMethod).Name[..14] != "IMachineMethod")
+ {
+ throw new NotSupportedException("IMachineMethod type name not begin with IMachineMethod");
+ }
+ var functionName = "Set" + typeof(TMachineMethod).Name[14..] + "Async";
+ return InvokeSet(machineMethod, functionName, parameters, datas);
+ }
+
///
/// 反射方式调用设置方法
///
@@ -36,7 +74,7 @@ namespace Modbus.Net
public static Task> InvokeSet(this IMachineMethod machineMethod, string functionName, object[] parameters, T datas)
{
var machineMethodType = machineMethod.GetType();
- var machineSetMethod = machineMethodType.GetMethod("Set" + functionName + "Async");
+ var machineSetMethod = machineMethodType.GetMethod(functionName);
object[] allParams = new object[parameters.Length + 1];
Array.Copy(parameters, allParams, parameters.Length);
allParams[parameters.Length] = datas;
diff --git a/Modbus.Net/Modbus.Net/Utility/UtilityMethodReflectionCall.cs b/Modbus.Net/Modbus.Net/Utility/UtilityMethodReflectionCall.cs
index 088ea58..03ae572 100644
--- a/Modbus.Net/Modbus.Net/Utility/UtilityMethodReflectionCall.cs
+++ b/Modbus.Net/Modbus.Net/Utility/UtilityMethodReflectionCall.cs
@@ -8,6 +8,24 @@ namespace Modbus.Net
///
public static class UtilityMethodReflectionCall
{
+ ///
+ /// 反射方式调用获取方法
+ ///
+ /// 方法组的类型
+ /// 要返回的数据类型
+ /// 方法组
+ /// 参数
+ /// 返回的数据
+ public static Task> InvokeGet(this IUtilityMethod utilityMethod, object[] parameters) where TUtilityMethod : IUtilityMethod
+ {
+ if (typeof(TUtilityMethod).Name[..14] != "IUtilityMethod")
+ {
+ throw new NotSupportedException("IUtilityMethod type name not begin with IUtilityMethod");
+ }
+ var functionName = "Get" + typeof(TUtilityMethod).Name[14..] + "Async";
+ return InvokeGet(utilityMethod, functionName, parameters);
+ }
+
///
/// 反射方式调用获取方法
///
@@ -19,11 +37,30 @@ namespace Modbus.Net
public static Task> InvokeGet(this IUtilityMethod utilityMethod, string functionName, object[] parameters)
{
var utilityMethodType = utilityMethod.GetType();
- var utilityGetMethod = utilityMethodType.GetMethod("Get" + functionName + "Async");
+ var utilityGetMethod = utilityMethodType.GetMethod(functionName);
var ans = utilityGetMethod.Invoke(utilityMethod, parameters);
return (Task>)ans;
}
+ ///
+ /// 反射方式调用设置方法
+ ///
+ /// 方法组的类型
+ /// 要设置的数据类型
+ /// 方法组
+ /// 参数
+ /// 要设置的数据
+ /// 设置是否成功
+ public static Task> InvokeSet(this IUtilityMethod utilityMethod, object[] parameters, T datas) where TUtilityMethod : IUtilityMethod
+ {
+ if (typeof(TUtilityMethod).Name[..14] != "IUtilityMethod")
+ {
+ throw new NotSupportedException("IUtilityMethod type name not begin with IUtilityMethod");
+ }
+ var functionName = "Set" + typeof(TUtilityMethod).Name[14..] + "Async";
+ return InvokeSet(utilityMethod, functionName, parameters, datas);
+ }
+
///
/// 反射方式调用设置方法
///
@@ -36,7 +73,7 @@ namespace Modbus.Net
public static Task> InvokeSet(this IUtilityMethod utilityMethod, string functionName, object[] parameters, T datas)
{
var utilityMethodType = utilityMethod.GetType();
- var utilitySetMethod = utilityMethodType.GetMethod("Set" + functionName + "Async");
+ var utilitySetMethod = utilityMethodType.GetMethod(functionName);
object[] allParams = new object[parameters.Length + 1];
Array.Copy(parameters, allParams, parameters.Length);
allParams[parameters.Length] = datas;