diff --git a/Constants/XStringHubAction.cs b/Constants/XStringHubAction.cs
new file mode 100644
index 0000000..2cf4c3e
--- /dev/null
+++ b/Constants/XStringHubAction.cs
@@ -0,0 +1,10 @@
+using xExceptions.Attributes;
+
+namespace xStringService.Constants
+{
+ public enum XStringHubAction
+ {
+ [StringValue("ItemsDeleted")]
+ ItemsDeleted
+ }
+}
\ No newline at end of file
diff --git a/Controller/XStringServiceControllerBase.cs b/Controllers/XStringServiceControllerBase.cs
similarity index 88%
rename from Controller/XStringServiceControllerBase.cs
rename to Controllers/XStringServiceControllerBase.cs
index e96e661..7d88a31 100644
--- a/Controller/XStringServiceControllerBase.cs
+++ b/Controllers/XStringServiceControllerBase.cs
@@ -12,7 +12,7 @@ using xModels.Dtos;
using xStringService.Interfaces;
using xStringService.Models.Dtos;
-namespace xStringService.Controllerppa
+namespace xStringService.Controllers
{
public abstract class XStringServiceControllerBase : XIBaseProviderController, IXStringServiceControllerActions
{
@@ -243,7 +243,7 @@ namespace xStringService.Controllerppa
///
///
[HttpGet("QueryResourceIds")]
- public virtual async Task>> QueryResourceIds(
+ public virtual ActionResult> QueryResourceIds(
[FromQuery] XQuery query
)
{
@@ -252,7 +252,7 @@ namespace xStringService.Controllerppa
try
{
//
- var result = await StringProvider
+ var result = StringProvider
.QueryResourceIds(query);
//
@@ -358,12 +358,16 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.Add(
value: value,
resource: resource,
- language: language
+ language: language,
+ connectionId: connectionId
);
//
@@ -396,12 +400,16 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.Update(
value: value,
resource: resource,
- language: language
+ language: language,
+ connectionId: connectionId
);
//
@@ -434,12 +442,16 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.AddOrUpdate(
value: value,
resource: resource,
- language: language
+ language: language,
+ connectionId: connectionId
);
//
@@ -469,7 +481,13 @@ namespace xStringService.Controllerppa
try
{
//
- var result = await StringProvider.AddEntity(item);
+ var connectionId = GetConnectionId();
+
+ //
+ var result = await StringProvider.AddEntity(
+ item: item,
+ connectionId: connectionId
+ );
//
return Ok(result.
@@ -497,9 +515,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
- .UpdateEntity(item);
+ .UpdateEntity(
+ item: item,
+ connectionId: connectionId
+ );
//
return Ok(result.
@@ -527,9 +551,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
- .AddOrUpdateEntity(item);
+ .AddOrUpdateEntity(
+ item: item,
+ connectionId: connectionId
+ );
//
return Ok(result.
@@ -559,11 +589,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.AddByLocaleResource(
item: item,
- resource: resource
+ resource: resource,
+ connectionId: connectionId
);
//
@@ -594,11 +628,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.UpdateByLocaleResource(
item: item,
- resource: resource
+ resource: resource,
+ connectionId: connectionId
);
//
@@ -629,11 +667,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.AddOrUpdateByLocaleResource(
item: item,
- resource: resource
+ resource: resource,
+ connectionId: connectionId
);
//
@@ -662,9 +704,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
- .AddByResource(item);
+ .AddByResource(
+ item: item,
+ connectionId: connectionId
+ );
//
return Ok(result.
@@ -695,9 +743,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
await StringProvider
- .RemoveLanguageResources(language);
+ .RemoveLanguageResources(
+ language: language,
+ connectionId: connectionId
+ );
//
return Ok();
@@ -724,9 +778,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
- .RemoveResource(resource);
+ .RemoveResource(
+ resource: resource,
+ connectionId: connectionId
+ );
//
return Ok(result.
@@ -756,11 +816,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
var result = await StringProvider
.Remove(
resource: resource,
- language: language
+ language: language,
+ connectionId: connectionId
);
//
@@ -789,9 +853,15 @@ namespace xStringService.Controllerppa
// Do ...
try
{
+ //
+ var connectionId = GetConnectionId();
+
//
await StringProvider
- .RemoveByResource(item);
+ .RemoveByResource(
+ item: item,
+ connectionId: connectionId
+ );
//
return Ok();
diff --git a/Hubs/XStringHub.cs b/Hubs/XStringHub.cs
new file mode 100644
index 0000000..78076c9
--- /dev/null
+++ b/Hubs/XStringHub.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.Logging;
+using xPushService.Base;
+using xStringService.Models.Entities;
+
+namespace xStringService.Hubs
+{
+ public class XStringHub : XBaseEntityHub
+ {
+ //
+ #region Constructor ...
+ public XStringHub(ILogger logger) : base(logger)
+ { }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Interfaces/IXStringProvider.cs b/Interfaces/IXStringProvider.cs
index 2d3b82e..6e9c08f 100644
--- a/Interfaces/IXStringProvider.cs
+++ b/Interfaces/IXStringProvider.cs
@@ -2,9 +2,11 @@ using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.SignalR;
using xCommons.Configurations;
using xDataService.Configuration;
using xModels.Dtos;
+using xStringService.Hubs;
using xStringService.Interfaces.Entities;
using xStringService.Models.Dtos;
using xStringService.Models.Entities;
@@ -15,6 +17,7 @@ namespace xStringService.Interfaces
{
//
#region Props ...
+ IHubContext Hub { get; }
IXStringRepository Repository { get; }
XAppConfiguration AppConfiguration { get; }
XDataServiceConfiguration DataConfiguration { get; }
@@ -38,7 +41,7 @@ namespace xStringService.Interfaces
string resource,
string language = null
);
-
+
///
/// Retrieve Specified Resource ...
///
@@ -83,7 +86,7 @@ namespace xStringService.Interfaces
///
///
///
- Task> QueryResourceIds(XQuery query);
+ XQueryResult QueryResourceIds(XQuery query);
///
/// Query Specified Language Resources ...
@@ -129,11 +132,13 @@ namespace xStringService.Interfaces
///
///
///
+ ///
///
Task Add(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
);
///
@@ -142,11 +147,13 @@ namespace xStringService.Interfaces
///
///
///
+ ///
///
Task Update(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
);
///
@@ -155,43 +162,59 @@ namespace xStringService.Interfaces
///
///
///
+ ///
///
Task AddOrUpdate(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
);
///
/// Add Specified Resource ...
///
///
+ ///
///
- Task AddEntity(XStringDto item);
+ Task AddEntity(
+ XStringDto item,
+ string connectionId = null
+ );
///
/// Update Specified Entity ...
///
///
+ ///
///
- Task UpdateEntity(XStringDto item);
+ Task UpdateEntity(
+ XStringDto item,
+ string connectionId = null
+ );
///
/// Add Or Update Specified Entitiy ...
///
///
+ ///
///
- Task AddOrUpdateEntity(XStringDto item);
+ Task AddOrUpdateEntity(
+ XStringDto item,
+ string connectionId = null
+ );
///
/// Add Specified Locale Resource ...
///
///
///
+ ///
///
Task AddByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
);
///
@@ -199,10 +222,12 @@ namespace xStringService.Interfaces
///
///
///
+ ///
///
Task UpdateByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
);
///
@@ -210,18 +235,24 @@ namespace xStringService.Interfaces
///
///
///
+ ///
///
Task AddOrUpdateByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
);
///
/// Add Or Update all XResourceDto(s) Locales ...
///
///
+ ///
///
- Task> AddByResource(XResourceDto item);
+ Task> AddByResource(
+ XResourceDto item,
+ string connectionId = null
+ );
#endregion
//
@@ -230,33 +261,47 @@ namespace xStringService.Interfaces
/// Remove all Specified Language's Resources ...
///
///
+ ///
///
- Task RemoveLanguageResources(string language);
+ Task RemoveLanguageResources(
+ string language,
+ string connectionId = null
+ );
///
/// Remove all Specified Resource Ids instances ...
///
///
+ ///
///
- Task> RemoveResource(string resource);
+ Task> RemoveResource(
+ string resource,
+ string connectionId = null
+ );
///
/// Remove Specified Resource ...
///
///
///
+ ///
///
Task Remove(
string resource,
- string language = null
+ string language = null,
+ string connectionId = null
);
///
/// Remove all Resource of Specified XResourceDto ...
///
///
+ ///
///
- Task RemoveByResource(XResourceDto item);
+ Task RemoveByResource(
+ XResourceDto item,
+ string connectionId = null
+ );
#endregion
}
}
\ No newline at end of file
diff --git a/Interfaces/IXStringServiceControllerActions.cs b/Interfaces/IXStringServiceControllerActions.cs
index 522e3b7..d5d8d23 100644
--- a/Interfaces/IXStringServiceControllerActions.cs
+++ b/Interfaces/IXStringServiceControllerActions.cs
@@ -75,7 +75,7 @@ namespace xStringService.Interfaces
///
///
///
- Task>> QueryResourceIds(
+ ActionResult> QueryResourceIds(
[FromQuery] XQuery query
);
diff --git a/Providers/XStringProvider.cs b/Providers/XStringProvider.cs
index 05e192a..04d9c31 100644
--- a/Providers/XStringProvider.cs
+++ b/Providers/XStringProvider.cs
@@ -3,13 +3,18 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
+using DnsClient.Protocol;
+using Microsoft.AspNetCore.SignalR;
using xCommons.Configurations;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Extensions;
using xExceptions.Constants;
using xModels.Dtos;
+using xPushService.Constants;
+using xStringService.Constants;
using xStringService.Extensions;
+using xStringService.Hubs;
using xStringService.Interfaces;
using xStringService.Interfaces.Entities;
using xStringService.Models.Dtos;
@@ -21,6 +26,7 @@ namespace xStringService.Providers
{
//
#region Props ...
+ public IHubContext Hub { get; }
public IXStringRepository Repository { get; }
public XAppConfiguration AppConfiguration { get; }
public XDataServiceConfiguration DataConfiguration { get; }
@@ -31,13 +37,15 @@ namespace xStringService.Providers
public XStringProvider(
IXStringRepository repository,
XAppConfiguration appConfiguration,
- XDataServiceConfiguration dataConfiguration
+ XDataServiceConfiguration dataConfiguration,
+ IHubContext hub = null
)
{
//
Repository = repository;
AppConfiguration = appConfiguration;
DataConfiguration = dataConfiguration;
+ Hub = hub;
}
#endregion
@@ -304,7 +312,7 @@ namespace xStringService.Providers
///
///
///
- public async Task> QueryResourceIds(XQuery query)
+ public XQueryResult QueryResourceIds(XQuery query)
{
//
// Normalize ...
@@ -410,7 +418,7 @@ namespace xStringService.Providers
TotalPages = entityResult.TotalPages,
TotalItems = entityResult.TotalItems,
TotalFilteredPages = entityResult.TotalFilteredPages,
- TotalFilteredItems = entityResult.TotalFilteredItems,
+ TotalFilteredItems = entityResult.TotalFilteredItems,
Items = entityResult.Items.Select(i => i.ToXStringDto()),
};
@@ -562,11 +570,13 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task Add(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
)
{
//
@@ -607,8 +617,17 @@ namespace xStringService.Providers
TranslatedValue = value,
ResourceTitle = resource,
};
- var added = await Repository.AddAsync(entity);
- result = !added.IsNullOrDefault();
+ entity = await Repository.AddAsync(entity);
+ result = !entity.IsNullOrDefault();
+ if (result)
+ {
+ //
+ await SendPush(
+ action: XBaseEntityHubAction.Add.GetStringValue(),
+ entityId: entity.Id,
+ connectionId: connectionId
+ );
+ }
//
return result;
@@ -620,11 +639,13 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task Update(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
)
{
//
@@ -674,6 +695,15 @@ namespace xStringService.Providers
entity.TranslatedValue = value;
entity = await Repository.UpdateAsync(entity.Id, entity);
result = !entity.IsNullOrDefault();
+ if (result)
+ {
+ //
+ await SendPush(
+ action: XBaseEntityHubAction.Update.GetStringValue(),
+ entityId: entity.Id,
+ connectionId: connectionId
+ );
+ }
//
return result;
@@ -685,11 +715,13 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task AddOrUpdate(
string resource,
string value,
- string language = null
+ string language = null,
+ string connectionId = null
)
{
//
@@ -738,8 +770,12 @@ namespace xStringService.Providers
/// Add Specified Resource ...
///
///
+ ///
///
- public async Task AddEntity(XStringDto item)
+ public async Task AddEntity(
+ XStringDto item,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -787,6 +823,13 @@ namespace xStringService.Providers
XException.ActionFailed.Throw();
}
+ //
+ await SendPush(
+ action: XBaseEntityHubAction.Add.GetStringValue(),
+ entityId: result.Id,
+ connectionId: connectionId
+ );
+
//
return result.ToXStringDto();
}
@@ -795,8 +838,12 @@ namespace xStringService.Providers
/// Update Specified Entity ...
///
///
+ ///
///
- public async Task UpdateEntity(XStringDto item)
+ public async Task UpdateEntity(
+ XStringDto item,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -852,6 +899,11 @@ namespace xStringService.Providers
//
XStringDto result = entity.ToXStringDto();
+ await SendPush(
+ action: XBaseEntityHubAction.Update.GetStringValue(),
+ entityId: entity.Id,
+ connectionId: connectionId
+ );
//
return result;
@@ -861,8 +913,12 @@ namespace xStringService.Providers
/// Add Or Update Specified Entitiy ...
///
///
+ ///
///
- public async Task AddOrUpdateEntity(XStringDto item)
+ public async Task AddOrUpdateEntity(
+ XStringDto item,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -897,11 +953,11 @@ namespace xStringService.Providers
XStringDto result = null;
if (!isExists)
{
- result = await AddEntity(item);
+ result = await AddEntity(item, connectionId);
}
else
{
- result = await UpdateEntity(item);
+ result = await UpdateEntity(item, connectionId);
}
if (result.IsNullOrDefault())
{
@@ -917,10 +973,12 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task AddByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
)
{
//
@@ -954,7 +1012,7 @@ namespace xStringService.Providers
ResourceTitle = resource,
TranslatedValue = item.Value
};
- result = await AddEntity(result);
+ result = await AddEntity(result, connectionId);
//
return result;
@@ -965,10 +1023,12 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task UpdateByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
)
{
//
@@ -1015,6 +1075,13 @@ namespace xStringService.Providers
//
XStringDto result = entity.ToXStringDto();
+ await SendPush(
+ action: XBaseEntityHubAction.Update.GetStringValue(),
+ entityId: entity.Id,
+ connectionId: connectionId
+ );
+
+ //
return result;
}
@@ -1023,10 +1090,12 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task AddOrUpdateByLocaleResource(
XLocaleResourceDto item,
- string resource
+ string resource,
+ string connectionId = null
)
{
//
@@ -1079,8 +1148,12 @@ namespace xStringService.Providers
/// Add Or Update all XResourceDto(s) Locales ...
///
///
+ ///
///
- public async Task> AddByResource(XResourceDto item)
+ public async Task> AddByResource(
+ XResourceDto item,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -1109,8 +1182,12 @@ namespace xStringService.Providers
/// Remove all Specified Language's Resources ...
///
///
+ ///
///
- public async Task RemoveLanguageResources(string language)
+ public async Task RemoveLanguageResources(
+ string language,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -1123,15 +1200,37 @@ namespace xStringService.Providers
//
var entities = await Repository
.FindManyAsync(e => e.Language.ToNormalString() == language.ToNormalString());
- await Repository.RemoveRangeAsync(entities);
+
+ //
+ try
+ {
+ //
+ await Repository.RemoveRangeAsync(entities);
+
+ //
+ var entitieIds = entities.Select(e => e.Id);
+ await SendCustomPush(
+ action: XStringHubAction.ItemsDeleted.GetStringValue(),
+ payLoad: entitieIds.ToJSON(),
+ connectionId: connectionId
+ );
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
}
///
/// Remove all Specified Resource Ids instances ...
///
///
+ ///
///
- public async Task> RemoveResource(string resource)
+ public async Task> RemoveResource(
+ string resource,
+ string connectionId = null
+ )
{
//
// Validate ...
@@ -1153,6 +1252,18 @@ namespace xStringService.Providers
}
}
+ //
+ if (result.HasChild())
+ {
+ //
+ var ids = result.Select(i => i.Id);
+ await SendCustomPush(
+ action: XStringHubAction.ItemsDeleted.GetStringValue(),
+ payLoad: ids.ToJSON(),
+ connectionId: connectionId
+ );
+ }
+
//
return result;
}
@@ -1162,10 +1273,12 @@ namespace xStringService.Providers
///
///
///
+ ///
///
public async Task Remove(
string resource,
- string language = null
+ string language = null,
+ string connectionId = null
)
{
//
@@ -1215,6 +1328,15 @@ namespace xStringService.Providers
// Delete ...
entity = await Repository.RemoveAsync(entity.Id);
result = !entity.IsNullOrDefault();
+ if (result)
+ {
+ //
+ await SendPush(
+ action: XBaseEntityHubAction.Delete.GetStringValue(),
+ entityId: entity.Id,
+ connectionId: connectionId
+ );
+ }
//
return result;
@@ -1224,8 +1346,12 @@ namespace xStringService.Providers
/// Remove all Resource of Specified XResourceDto ...
///
///
+ ///
///
- public async Task RemoveByResource(XResourceDto item)
+ public async Task RemoveByResource(
+ XResourceDto item,
+ string connectionId = null
+ )
{
//
bool isValid =
@@ -1237,7 +1363,7 @@ namespace xStringService.Providers
XException.InvalidArgs.Throw();
}
- //
+ //
foreach (var locale in item.Locales)
{
//
@@ -1248,5 +1374,100 @@ namespace xStringService.Providers
}
}
#endregion
+
+ //
+ #region Hub Actions ...
+ ///
+ /// Send Specified Hub Action Notifications ...
+ ///
+ ///
+ ///
+ ///
+ public async Task SendPush(
+ string action,
+ int entityId,
+ string connectionId = null
+ )
+ {
+ //
+ var hubActions = new List
+ {
+ XBaseEntityHubAction.Add.GetStringValue(),
+ XBaseEntityHubAction.Delete.GetStringValue(),
+ XBaseEntityHubAction.Update.GetStringValue(),
+ };
+
+ //
+ // Validate ...
+ var isValid =
+ entityId > 0 &&
+ !Hub.IsNull() &&
+ !action.IsNullOrEmpty() &&
+ hubActions.Contains(action);
+ if (!isValid)
+ {
+ return;
+ }
+
+ //
+ // Retrieve and Validate Entity ...
+ XString entity = null;
+ try
+ {
+ entity = await Repository.GetAsync(entityId);
+ }
+ catch { }
+ isValid = !entity.IsNullOrDefault();
+ if (!isValid)
+ {
+ return;
+ }
+
+ //
+ var clients = Hub.Clients.All;
+ if (!connectionId.IsNullOrEmpty())
+ {
+ clients = Hub.Clients.AllExcept(connectionId);
+ }
+ await clients.SendAsync(action, entity, connectionId);
+ }
+
+ ///
+ /// Send Custom Push Message ...
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task SendCustomPush(
+ string action,
+ string payLoad,
+ string connectionId = null
+ )
+ {
+ //
+ var customActions = new List
+ {
+ XStringHubAction.ItemsDeleted.GetStringValue(),
+ };
+
+ //
+ // Validate ...
+ var isValid = !action.IsNullOrEmpty() &&
+ customActions.Contains(action);
+ if (!isValid)
+ {
+ return;
+ }
+
+ //
+ var clients = Hub.Clients.All;
+ if (!connectionId.IsNullOrEmpty())
+ {
+ clients = Hub.Clients.AllExcept(connectionId);
+ }
+ await clients.SendAsync(action, payLoad, connectionId);
+ }
+ #endregion
}
}
\ No newline at end of file
diff --git a/xStringService.csproj b/xStringService.csproj
index 5e3d087..ed0f07f 100644
--- a/xStringService.csproj
+++ b/xStringService.csproj
@@ -20,9 +20,16 @@
+
+
+
+
+
+
+
-
+