From cb8e95dcea55476ccc90fa4fcb11a1148d76eba5 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Tue, 9 Dec 2025 03:11:48 +0330 Subject: [PATCH] add support for Provider Base Controller and also resolve some refactoring issues ... --- Controllers/XTagServiceControllerBase.cs | 5 +- Interfaces/IXBaseTagProvider.cs | 26 +- Interfaces/IXTagProvider.cs | 48 ++-- Providers/XBaseTagProvider.cs | 53 +++- Providers/XTagProvider.cs | 305 +++++++++++++++-------- 5 files changed, 288 insertions(+), 149 deletions(-) diff --git a/Controllers/XTagServiceControllerBase.cs b/Controllers/XTagServiceControllerBase.cs index 98c4d14..3dd2bba 100644 --- a/Controllers/XTagServiceControllerBase.cs +++ b/Controllers/XTagServiceControllerBase.cs @@ -17,7 +17,10 @@ using xTagService.Models.Entities; namespace xTagService.Controllers { - public class XTagServiceControllerBase : XIBaseProviderController, IXTagServiceControllerActions + /// + /// a Controller base Class which implement based Actions to Provides Tag Provider Access ... + /// + public abstract class XTagServiceControllerBase : XIBaseProviderController, IXTagServiceControllerActions { // #region Props ... diff --git a/Interfaces/IXBaseTagProvider.cs b/Interfaces/IXBaseTagProvider.cs index 8944b97..b093104 100644 --- a/Interfaces/IXBaseTagProvider.cs +++ b/Interfaces/IXBaseTagProvider.cs @@ -40,10 +40,12 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task Attach( string tag, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ); /// @@ -51,10 +53,12 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task Detach( string tag, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ); /// @@ -62,10 +66,12 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task Add( XTagDto model, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ); /// @@ -177,17 +183,23 @@ namespace xTagService.Interfaces /// Remove Specified Dto ... /// /// + /// /// Task Remove( - int id + int id, + string connectionId = null ); /// /// Remove All Specified Tags ... /// /// + /// /// - Task RemoveTagsFor(TKey forProvidedId); + Task RemoveTagsFor( + TKey forProvidedId, + string connectionId = null + ); /// /// Update Specified Dto ... @@ -195,11 +207,13 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task Update( int id, XTagDto model, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ); /// diff --git a/Interfaces/IXTagProvider.cs b/Interfaces/IXTagProvider.cs index b29958a..07a540f 100644 --- a/Interfaces/IXTagProvider.cs +++ b/Interfaces/IXTagProvider.cs @@ -60,6 +60,30 @@ namespace xTagService.Interfaces string connectionId = null ); + /// + /// Update Specified Dto ... + /// + /// + /// + /// + /// + Task Update( + int id, + XTagDto model, + string connectionId = null + ); + + /// + /// Remove Specified Dto ... + /// + /// + /// + /// + Task Remove( + int id, + string connectionId = null + ); + /// /// Retrieve Specified Item as Dto ... /// @@ -112,30 +136,6 @@ namespace xTagService.Interfaces Expression> whereClause ); - /// - /// Remove Specified Dto ... - /// - /// - /// - /// - Task Remove( - int id, - string connectionId = null - ); - - /// - /// Update Specified Dto ... - /// - /// - /// - /// - /// - Task Update( - int id, - XTagDto model, - string connectionId = null - ); - /// /// Count Exists Entities ... /// diff --git a/Providers/XBaseTagProvider.cs b/Providers/XBaseTagProvider.cs index 0ee8438..41c563c 100644 --- a/Providers/XBaseTagProvider.cs +++ b/Providers/XBaseTagProvider.cs @@ -68,10 +68,12 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task Attach( string tag, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ) { // @@ -103,7 +105,8 @@ namespace xTagService.Providers { Tag = tag, References = new List { identifier } - }); + }, + connectionId); } // // Update Exists Tag Enttiy ... @@ -119,7 +122,11 @@ namespace xTagService.Providers // result.References.Add(identifier); - result = await Provider.Update(result.Id, result); + result = await Provider.Update( + result.Id, + result, + connectionId + ); isValid = !result.IsNullOrDefault(); if (!isValid) { @@ -136,10 +143,12 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task Detach( string tag, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ) { // @@ -187,7 +196,11 @@ namespace xTagService.Providers .References .Where(rf => rf.ToNormalString() != identifier.ToNormalString()) .ToList(); - result = await Provider.Update(result.Id, result); + result = await Provider.Update( + result.Id, + result, + connectionId + ); // return result; @@ -198,10 +211,12 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task Add( XTagDto model, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ) { // @@ -228,7 +243,7 @@ namespace xTagService.Providers } // - model = await Provider.Add(model); + model = await Provider.Add(model, connectionId); // return model; @@ -833,9 +848,11 @@ namespace xTagService.Providers /// Remove Specified Dto ... /// /// + /// /// public async Task Remove( - int id + int id, + string connectionId = null ) { // @@ -853,7 +870,7 @@ namespace xTagService.Providers } // - var result = await Provider.Remove(id); + var result = await Provider.Remove(id, connectionId); if (result.IsNullOrDefault()) { XException.ActionFailed.Throw(); @@ -867,8 +884,12 @@ namespace xTagService.Providers /// Remove All Specified Tags ... /// /// + /// /// - public async Task RemoveTagsFor(TKey forProvidedId) + public async Task RemoveTagsFor( + TKey forProvidedId, + string connectionId = null + ) { // var result = false; @@ -885,7 +906,7 @@ namespace xTagService.Providers try { // - await Detach(dto.Tag, forProvidedId); + await Detach(dto.Tag, forProvidedId, connectionId); if (!result) { result = true; @@ -905,11 +926,13 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task Update( int id, XTagDto model, - TKey forProvidedId + TKey forProvidedId, + string connectionId = null ) { // @@ -927,7 +950,11 @@ namespace xTagService.Providers } // - var result = await Provider.Update(id, model); + var result = await Provider.Update( + id, + model, + connectionId + ); if (result.IsNullOrDefault()) { XException.ActionFailed.Throw(); diff --git a/Providers/XTagProvider.cs b/Providers/XTagProvider.cs index b08fd2a..2d78881 100644 --- a/Providers/XTagProvider.cs +++ b/Providers/XTagProvider.cs @@ -9,6 +9,7 @@ using xDataService.Configuration; using xExceptions.Constants; using xIdentityService.Interfaces; using xModels.Dtos; +using xPushService.Constants; using xTagService.Extensions; using xTagService.Hubs; using xTagService.Interfaces; @@ -125,32 +126,172 @@ namespace xTagService.Providers /// Add Specified Tag ... /// /// + /// /// - public async Task Add(XTagDto model) + public async Task Add( + XTagDto model, + string connectionId = null + ) { // XTagDto result = null; // + // Converts to Entity ... + var entity = model.FromDto(); if (!model.IsNullOrDefault()) { // - // Converts to Entity ... - var entitiy = model.FromDto(); - if (entitiy.IsNullOrDefault()) + // Validate ... + if (entity.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // - entitiy = await Repository.AddAsync(entitiy); - if (entitiy.IsNullOrDefault()) + entity = await Repository.AddAsync(entity); + if (entity.IsNullOrDefault()) { XException.ActionFailed.Throw(); } // - result = ToDto(entitiy); + result = ToDto(entity); + } + + // + if (!result.IsNullOrDefault()) + { + // + await SendPush( + action: XBaseEntityHubAction.Add.GetStringValue(), + payLoad: entity.ToJSON(camelCase: true), + connectionId: connectionId + ); + } + + // + return result; + } + + /// + /// Update Specified Dto ... + /// + /// + /// + /// + /// + /// + public async Task Update( + int id, + XTagDto model, + string connectionId = null + ) + { + // + // Validate ... + var isValid = id.IsValidIntId(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + XTagDto result = null; + + // + // Check Exists ... + isValid = await IsExists(id); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + var entity = await Repository.GetAsync(id); + if (entity.IsNullOrDefault()) + { + XException.NotFound.Throw(); + } + + // + var tagEntity = model.FromDto(); + entity = entity.UpdateData( + updateWith: entity, + propertyBlackList: new List + { + nameof(XTagDto.Id), + nameof(XTagDto.References) + } + ); + entity.References = tagEntity.References; + entity = await Repository.UpdateAsync(id, entity); + if (!entity.IsNullOrDefault()) + { + result = ToDto(entity); + } + + // + if (!result.IsNullOrDefault()) + { + // + await SendPush( + action: XBaseEntityHubAction.Update.GetStringValue(), + payLoad: entity.ToJSON(camelCase: true), + connectionId: connectionId + ); + } + + // + return result; + } + + /// + /// Remove Specified Dto ... + /// + /// + /// + /// + public async Task Remove( + int id, + string connectionId = null + ) + { + // + // Validate ... + var isValid = id.IsValidIntId(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Exists ... + isValid = await IsExists(id); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + var entity = await Repository.RemoveAsync(id); + + // + XTagDto result = null; + if (!entity.IsNullOrDefault()) + { + result = ToDto(entity); + } + + // + if (!result.IsNullOrDefault()) + { + // + await SendPush( + action: XBaseEntityHubAction.Delete.GetStringValue(), + payLoad: entity.ToJSON(camelCase: true), + connectionId: connectionId + ); } // @@ -333,104 +474,6 @@ namespace xTagService.Providers return result; } - /// - /// Remove Specified Dto ... - /// - /// - /// - public async Task Remove( - int id - ) - { - // - // Validate ... - var isValid = id.IsValidIntId(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Exists ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var entity = await Repository.RemoveAsync(id); - - // - XTagDto result = null; - if (!entity.IsNullOrDefault()) - { - result = ToDto(entity); - } - - // - return result; - } - - /// - /// Update Specified Dto ... - /// - /// - /// - /// - /// - public async Task Update( - int id, - XTagDto model - ) - { - // - // Validate ... - var isValid = id.IsValidIntId(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - XTagDto result = null; - - // - // Check Exists ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var entity = await Repository.GetAsync(id); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - var tagEntity = model.FromDto(); - entity = entity.UpdateData( - updateWith: entity, - propertyBlackList: new List - { - nameof(XTagDto.Id), - nameof(XTagDto.References) - } - ); - entity.References = tagEntity.References; - entity = await Repository.UpdateAsync(id, entity); - if (!entity.IsNullOrDefault()) - { - result = ToDto(entity); - } - - // - return result; - } - /// /// Count Exists Entities ... /// @@ -472,5 +515,57 @@ namespace xTagService.Providers return result; } #endregion + + // + #region Hub Actions ... + /// + /// Send Custom Push Message ... + /// + /// + /// + /// + /// + public async Task SendPush( + string action, + string payLoad, + string connectionId = null + ) + { + // + var actions = new List + { + XBaseEntityHubAction.Add.GetStringValue(), + XBaseEntityHubAction.Update.GetStringValue(), + XBaseEntityHubAction.Delete.GetStringValue(), + XBaseEntityHubAction.AddMany.GetStringValue(), + XBaseEntityHubAction.DeleteMany.GetStringValue(), + XBaseEntityHubAction.UpdateMany.GetStringValue(), + XBaseEntityHubAction.AddOrUpdate.GetStringValue(), + }; + + // + // Validate ... + var isValid = + !Hub.IsNull() && + !action.IsNullOrEmpty() && + actions.Contains(action); + if (!isValid) + { + return; + } + + // + var clients = Hub.Clients.All; + if (!connectionId.IsNullOrEmpty()) + { + clients = Hub.Clients.AllExcept(connectionId); + } + try + { + await clients.SendAsync(action, payLoad, connectionId); + } + catch { } + } + #endregion } } \ No newline at end of file