diff --git a/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs b/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs index 25072621..64c89157 100644 --- a/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs +++ b/TIAMSharedUI/Shared/Components/Grids/TiamGrid.cs @@ -153,14 +153,12 @@ namespace TIAMSharedUI.Shared.Components.Grids SignalRClient.PostDataAsync(messageTag, dataItem, async repsonse => { - if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null) + if (repsonse.Status != SignalResponseStatus.Success || repsonse.ResponseData == null || !RefreshDataSourceItem(repsonse.ResponseData, isDelete)) { RefreshDataSourceAsync().Forget(); return; } - RefreshDataSourceItem(repsonse.ResponseData, isDelete); - await OnDataSourceItemChanged.InvokeAsync(dataItem); await InvokeAsync(StateHasChanged); }).Forget(); @@ -168,8 +166,14 @@ namespace TIAMSharedUI.Shared.Components.Grids //transfer = await devAdminSignalClient.PostDataAsync(SignalRTags.UpdateTransferAsync, transfer); } - public void RefreshDataSourceItem(TDataItem dataItem, bool isDelete, bool invokeItemChanged = true) + public bool RefreshDataSourceItem(TDataItem dataItem, bool isDelete, bool invokeItemChanged = true) { + if (dataItem.Id.IsNullOrEmpty()) + { + Logger.Error($"dataItem.Id.IsNullOrEmpty()"); + return false; + } + var transferIndex = _dataSource.FindIndex(x => x.Id == dataItem.Id); if (isDelete && transferIndex > -1) _dataSource.RemoveAt(transferIndex); @@ -178,6 +182,8 @@ namespace TIAMSharedUI.Shared.Components.Grids if (transferIndex > -1) _dataSource[transferIndex] = dataItem; else _dataSource.Add(dataItem); } + + return true; } protected override Task SetParametersAsyncCore(ParameterView parameters) diff --git a/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs b/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs index 1d08a0a5..65d7d160 100644 --- a/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs +++ b/TIAMWebApp/Server/Services/DevAdminSignalRhub.cs @@ -1,5 +1,6 @@ using System.Collections.Concurrent; using System.Reflection; +using System.Reflection.Emit; using AyCode.Core.Extensions; using AyCode.Core.Loggers; using AyCode.Services.SignalRs; @@ -41,16 +42,45 @@ public enum MethodParamType : byte } [AttributeUsage(AttributeTargets.Method)] -public class SignalRAttribute(int messageTag, MethodParamType methodParamType, Type paramType = null) : Attribute +public class TagAttribute(int messageTag) : Attribute { public int MessageTag { get; init; } = messageTag; +} + +[AttributeUsage(AttributeTargets.Method)] +public class SignalRAttribute(int messageTag, MethodParamType methodParamType, Type paramType = null) : TagAttribute(messageTag) +{ public MethodParamType MethodParamType { get; init; } = methodParamType; public Type ParamType { get; init; } = paramType; } +public class MethodInfoModel(TAttribute attribute, MethodInfo methodInfo) where TAttribute : TagAttribute +{ + public TAttribute Attribute { get; set; } = attribute; + public MethodInfo MethodInfo { get; set; } = methodInfo; +} + +public class DynamicMethodCallModel where TAttribute : TagAttribute +{ + public object InstanceObject { get; init; } + public ConcurrentDictionary> MethodsByMessageTag { get; init; } = new(); + + public DynamicMethodCallModel(object instanceObject) + { + InstanceObject = instanceObject; + + foreach (var methodInfo in instanceObject.GetType().GetMethods()) + { + if (methodInfo.GetCustomAttribute(typeof(TAttribute)) is not TAttribute attribute) continue; + + MethodsByMessageTag[attribute.MessageTag] = new MethodInfoModel(attribute, methodInfo!); + } + } +} + public class DevAdminSignalRHub : Hub, IAcSignalRHubServer { - private readonly ConcurrentDictionary> _methodsByMessageTag = new(); + private readonly List> _dynamicMethodCallModels = new(); private readonly TIAM.Core.Loggers.Logger _logger; private readonly AdminDal _adminDal; @@ -62,25 +92,11 @@ public class DevAdminSignalRHub : Hub, IAcSignalRHubServe _adminDal = adminDal; _serviceProviderApiController = serviceProviderApiController; _transferDataApiController = transferDataApiController; + _logger = new(logWriters.ToArray()); - var methods = typeof(ServiceProviderAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0); - - _methodsByMessageTag[serviceProviderApiController] = new(); - foreach (var methodInfo in methods) - { - var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; - _methodsByMessageTag[serviceProviderApiController][atr.MessageTag] = methodInfo; - } - - methods = typeof(TransferDataAPIController).GetMethods().Where(x => x.GetCustomAttributes(typeof(SignalRAttribute), false).Length > 0); - _methodsByMessageTag[transferDataApiController] = new(); - - foreach (var methodInfo in methods) - { - var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; - _methodsByMessageTag[transferDataApiController][atr.MessageTag] = methodInfo; - } + _dynamicMethodCallModels.Add(new DynamicMethodCallModel(serviceProviderApiController)); + _dynamicMethodCallModels.Add(new DynamicMethodCallModel(transferDataApiController)); } @@ -121,33 +137,39 @@ public class DevAdminSignalRHub : Hub, IAcSignalRHubServe try { - foreach (var methodsByDeclaringObject in _methodsByMessageTag) + foreach (var methodsByDeclaringObject in _dynamicMethodCallModels) { - if (methodsByDeclaringObject.Value.TryGetValue(messageTag, out var methodInfo)) + if (!methodsByDeclaringObject.MethodsByMessageTag.TryGetValue(messageTag, out var methodInfoModel)) continue; + + object[]? paramValues = null; + var parameters = methodInfoModel.MethodInfo.GetParameters(); + + logText = $"Found the dynamic method for the tag! tag: {messageTag}; method: {methodsByDeclaringObject.InstanceObject.GetType().Name}.{methodInfoModel.MethodInfo.Name}"; + + if (parameters.Length > 0) { - var atr = methodInfo.GetCustomAttribute(typeof(SignalRAttribute)) as SignalRAttribute; - object[]? param = null; + _logger.Debug($"{logText}({parameters[0].ParameterType.Name})"); - if (atr.MethodParamType != MethodParamType.None) + paramValues = new object[1]; + if (parameters[0].ParameterType == typeof(Guid) || parameters[0].ParameterType == typeof(Guid?)) { - param = new object[1]; - if (atr.MethodParamType == MethodParamType.Id) - { - param[0] = message!.MessagePackTo().Id; - } - else - { - var msg = message!.MessagePackTo>(MessagePackSerializerOptions.Standard); - param[0] = msg.PostDataJson.JsonTo(atr.ParamType)!; - } + paramValues[0] = message!.MessagePackTo().Id; + } + else + { + var msg = message!.MessagePackTo>(MessagePackSerializerOptions.Standard); + paramValues[0] = msg.PostDataJson.JsonTo(parameters[0].ParameterType)!; } - - await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, methodInfo.InvokeMethod(methodsByDeclaringObject.Key, param)), requestId); - - return; } + else _logger.Debug($"{logText}()"); + + await ResponseToCaller(messageTag, new SignalResponseJsonMessage(SignalResponseStatus.Success, methodInfoModel.MethodInfo.InvokeMethod(methodsByDeclaringObject.InstanceObject, paramValues)), requestId); + + return; } + _logger.Debug($"Not found the dynamic method for the tag! tag: {messageTag};"); + switch (messageTag) { case SignalRTags.RemoveCompanyAsync: