add some new features in data service ...

This commit is contained in:
2026-05-15 19:41:43 +03:30
parent 35e1e08d50
commit f929414b9f
15 changed files with 1826 additions and 34 deletions
+215
View File
@@ -0,0 +1,215 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xModels.Base;
using xPushService.Constants;
using xPushService.Interfaces;
namespace xPushService.Base
{
public abstract class XBaseDtoHub<TEntity, TDto, TKey> : XBaseHub, IXBaseDtoHub<TEntity, TDto, TKey>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
{
//
#region Constructor ...
protected XBaseDtoHub(ILogger<XBaseHub> logger) : base(logger)
{ }
#endregion
//
#region Actions ...
/// <summary>
/// Notify a New Item added ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Add(
TDto item,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Add.GetStringValue(),
item.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify a New Item added ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AddOrUpdate(
TDto item,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
item.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify Add Many Items ...
/// </summary>
/// <param name="items"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AddMany(
IEnumerable<TDto> items,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
items.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify an Item Deleted ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Delete(
TDto item,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Delete.GetStringValue(),
item.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify Delete Many Items ...
/// </summary>
/// <param name="items"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task DeleteMany(
IEnumerable<TDto> items,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.DeleteMany.GetStringValue(),
items.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify an Item Updated ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Update(
TDto item,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.Update.GetStringValue(),
item.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
/// <summary>
/// Notify Update Many Items ...
/// </summary>
/// <param name="items"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task UpdateMany(
IEnumerable<TDto> items,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
if (!connectionId.IsNullOrEmpty())
{
//
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.UpdateMany.GetStringValue(),
items.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
#endregion
}
}
+423
View File
@@ -0,0 +1,423 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore.Query;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Interfaces;
using xIdentityService.Interfaces;
using xModels.Base;
using xModels.Dtos;
using xPushService.Constants;
using xPushService.Interfaces;
namespace xPushService.Base
{
public abstract class XBaseDtoProvider<TEntity, TDto, TKey> : IXBaseDtoProvider<TEntity, TDto, TKey>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
{
//
#region Properties ...
public IXIdentityProvider IdentityProvider { get; }
public XDataServiceConfiguration DataConfiguration { get; }
public IHubContext<XBaseDtoHub<TEntity, TDto, TKey>> Hub { get; }
public IXBaseRepositoryService<TEntity, TDto, TKey> Service { get; }
#endregion
//
#region Constructor ...
protected XBaseDtoProvider(
IXIdentityProvider identityProvider,
XDataServiceConfiguration dataConfiguration,
IHubContext<XBaseDtoHub<TEntity, TDto, TKey>> hub,
IXBaseRepositoryService<TEntity, TDto, TKey> service
)
{
//
Hub = hub;
Service = service;
IdentityProvider = identityProvider;
DataConfiguration = dataConfiguration;
}
#endregion
//
#region Actions ...
/// <summary>
/// add a new Item ...
/// </summary>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> AddAsync(
TDto item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.AddAsync(
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Update an Item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> UpdateAsync(
TKey id,
TDto item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.UpdateAsync(
id: id,
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Update.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// remove an Item by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> RemoveAsync(
TKey id,
bool softDelete = true,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.RemoveAsync(
id: id,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Delete.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// count all exists Items ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<int> CountAsync(
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.CountAsync(
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// Check an Item exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<bool> IsExistsAsync(
TKey id,
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve an Item by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> GetAsync(
TKey id,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.GetAsync(
id: id,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve all exists Items ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TDto>> GetAllAsync(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.GetAllAsync(
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find an Item by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> FindOneAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.FindOneAsync(
predicate: predicate,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find a collection of Items by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TDto>> FindManyAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.FindManyAsync(
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<XQueryResult<TDto>> QueryAsync(
XQuery query,
bool ignoreSoftDeleteds = true,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Service.QueryAsync(
query: query,
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
#endregion
//
#region Hub Actions ...
/// <summary>
/// Send Custom Push Message ...
/// </summary>
/// <param name="action"></param>
/// <param name="payLoad"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task SendPush(
string action,
string payLoad,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var actions = new List<string>
{
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() &&
!payLoad.IsNullOrEmpty() &&
actions.Contains(action);
if (!isValid)
{
return;
}
//
// Retrieve Connection Id ...
var clients = Hub.Clients.All;
if (!connectionId.IsNullOrEmpty())
{
clients = Hub.Clients.AllExcept(connectionId);
}
//
await clients.SendAsync(
action,
payLoad,
connectionId,
cancellationToken
);
}
#endregion
}
}
+57 -20
View File
@@ -1,14 +1,16 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xModels.Base;
using xPushService.Constants;
using xPushService.Interfaces;
namespace xPushService.Base
{
public abstract class XBaseEntityHub<TEntity, TKey> : XBaseHub
public abstract class XBaseEntityHub<TEntity, TKey> : XBaseHub, IXBaseEntityHub<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
//
@@ -23,8 +25,12 @@ namespace xPushService.Base
/// Notify a New Entity added ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Add(TEntity entity)
public async Task Add(
TEntity entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -36,7 +42,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.Add.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -45,8 +52,12 @@ namespace xPushService.Base
/// Notify a New Entity added ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AddOrUpdate(TEntity entity)
public async Task AddOrUpdate(
TEntity entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -58,7 +69,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -66,9 +78,13 @@ namespace xPushService.Base
/// <summary>
/// Notify Add Many Entities ...
/// </summary>
/// <param name="entity"></param>
/// <param name="entities"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AddMany(IEnumerable<TEntity> entities)
public async Task AddMany(
IEnumerable<TEntity> entities,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -80,7 +96,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.AddOrUpdate.GetStringValue(),
entities.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -89,8 +106,12 @@ namespace xPushService.Base
/// Notify an Entity Deleted ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Delete(TEntity entity)
public async Task Delete(
TEntity entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -102,7 +123,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.Delete.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -110,9 +132,13 @@ namespace xPushService.Base
/// <summary>
/// Notify Delete Many Entities ...
/// </summary>
/// <param name="entity"></param>
/// <param name="entities"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task DeleteMany(IEnumerable<TEntity> entities)
public async Task DeleteMany(
IEnumerable<TEntity> entities,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -124,7 +150,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.DeleteMany.GetStringValue(),
entities.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -133,8 +160,12 @@ namespace xPushService.Base
/// Notify an Entity Updated ...
/// </summary>
/// <param name="entity"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Update(TEntity entity)
public async Task Update(
TEntity entity,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -146,7 +177,8 @@ namespace xPushService.Base
.SendAsync(
XBaseEntityHubAction.Update.GetStringValue(),
entity.ToJSON(camelCase: true),
connectionId
connectionId,
cancellationToken
);
}
}
@@ -154,9 +186,13 @@ namespace xPushService.Base
/// <summary>
/// Notify Update Many Entities ...
/// </summary>
/// <param name="entity"></param>
/// <param name="entities"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task UpdateMany(IEnumerable<TEntity> entities)
public async Task UpdateMany(
IEnumerable<TEntity> entities,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
@@ -166,9 +202,10 @@ namespace xPushService.Base
await Clients
.AllExcept(connectionId)
.SendAsync(
XBaseEntityHubAction.UpdateMany.GetStringValue(),
entities.ToJSON(camelCase: true),
connectionId
XBaseEntityHubAction.UpdateMany.GetStringValue(),
entities.ToJSON(camelCase: true),
connectionId,
cancellationToken
);
}
}
+422
View File
@@ -0,0 +1,422 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore.Query;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Interfaces;
using xIdentityService.Interfaces;
using xModels.Base;
using xModels.Dtos;
using xPushService.Constants;
using xPushService.Interfaces;
namespace xPushService.Base
{
public abstract class XBaseEntityProvider<TEntity, TKey> : IXBaseEntityProviderr<TEntity, TKey>
where TEntity : XBaseEntity<TKey>
{
//
#region Properties ...
public IXIdentityProvider IdentityProvider { get; }
public IXBaseRepository<TEntity, TKey> Repository { get; }
public XDataServiceConfiguration DataConfiguration { get; }
public IHubContext<XBaseEntityHub<TEntity, TKey>> Hub { get; }
#endregion
//
#region Constructor ...
protected XBaseEntityProvider(
IXIdentityProvider identityProvider,
IXBaseRepository<TEntity, TKey> repository,
XDataServiceConfiguration dataConfiguration,
IHubContext<XBaseEntityHub<TEntity, TKey>> hub
)
{
//
Hub = hub;
Repository = repository;
IdentityProvider = identityProvider;
DataConfiguration = dataConfiguration;
}
#endregion
//
#region Actions ...
/// <summary>
/// add a new Item ...
/// </summary>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TEntity> AddAsync(
TEntity item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.AddAsync(
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Update an Item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TEntity> UpdateAsync(
TKey id,
TEntity item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.UpdateAsync(
id: id,
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Update.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// remove an Item by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TEntity> RemoveAsync(
TKey id,
bool softDelete = true,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.RemoveAsync(
id: id,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
var isValid = !result.IsNullOrDefault();
if (isValid)
{
//
await SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Delete.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// count all exists Items ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<int> CountAsync(
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.CountAsync(
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// Check an Item exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<bool> IsExistsAsync(
TKey id,
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve an Item by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TEntity> GetAsync(
TKey id,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.GetAsync(
id: id,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve all exists Items ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TEntity>> GetAllAsync(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.GetAllAsync(
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find an Item by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TEntity> FindOneAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.FindOneAsync(
predicate: predicate,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find a collection of Items by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TEntity>> FindManyAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.FindManyAsync(
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<XQueryResult<TEntity>> QueryAsync(
XQuery query,
bool ignoreSoftDeleteds = true,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await Repository.QueryAsync(
query: query,
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
#endregion
//
#region Hub Actions ...
/// <summary>
/// Send Custom Push Message ...
/// </summary>
/// <param name="action"></param>
/// <param name="payLoad"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task SendPush(
string action,
string payLoad,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var actions = new List<string>
{
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() &&
!payLoad.IsNullOrEmpty() &&
actions.Contains(action);
if (!isValid)
{
return;
}
//
// Retrieve Connection Id ...
var clients = Hub.Clients.All;
if (!connectionId.IsNullOrEmpty())
{
clients = Hub.Clients.AllExcept(connectionId);
}
//
await clients.SendAsync(
action,
payLoad,
connectionId,
cancellationToken
);
}
#endregion
}
}
+12 -2
View File
@@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
@@ -58,11 +59,20 @@ namespace xPushService.Base
//
#region Actions ...
public async Task SendCustomAction(string actionName, string payLoad)
public async Task SendCustomAction(
string actionName,
string payLoad,
CancellationToken cancellationToken = default
)
{
//
var connectionId = Context.ConnectionId;
await Clients.AllExcept(connectionId).SendAsync(actionName, payLoad, connectionId);
await Clients.AllExcept(connectionId).SendAsync(
actionName,
payLoad,
connectionId,
cancellationToken
);
}
#endregion
}
+403
View File
@@ -0,0 +1,403 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore.Query;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Interfaces;
using xIdentityService.Interfaces;
using xModels.Base;
using xModels.Dtos;
using xPushService.Constants;
using xPushService.Interfaces;
namespace xPushService.Base
{
public abstract class XBaseProvider<TEntity, TDto, TKey> : IXBaseProvider<TEntity, TDto, TKey>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
{
//
#region Props ...
public IXIdentityProvider IdentityProvider { get; }
public XDataServiceConfiguration DataConfiguration { get; }
public IHubContext<XBaseEntityHub<TEntity, TKey>> Hub { get; }
public IXBaseRepositoryService<TEntity, TDto, TKey> RepositoryService { get; }
#endregion
//
#region Actions ...
/// <summary>
/// add a new Dto ...
/// </summary>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> AddAsync(
TDto item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.AddAsync(
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
if (!result.IsNullOrDefault())
{
//
await SendPush(
action: XBaseEntityHubAction.Add.GetStringValue(),
payLoad: result.ToJSON(camelCase: true),
connectionId: connectionId
);
}
//
return result;
}
/// <summary>
/// Update an Dto values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> UpdateAsync(
TKey id,
TDto item,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.UpdateAsync(
id: id,
item: item,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
if (!result.IsNullOrDefault())
{
//
await SendPush(
action: XBaseEntityHubAction.Update.GetStringValue(),
payLoad: result.ToJSON(camelCase: true),
connectionId: connectionId
);
}
//
return result;
}
/// <summary>
/// remove an Dto by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="softDelete"></param>
/// <param name="saveChanges"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> RemoveAsync(
TKey id,
bool softDelete = true,
bool saveChanges = true,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.RemoveAsync(
id: id,
softDelete: softDelete,
saveChanges: saveChanges,
cancellationToken: cancellationToken
);
//
if (!result.IsNullOrDefault())
{
//
await SendPush(
action: XBaseEntityHubAction.Update.GetStringValue(),
payLoad: result.ToJSON(camelCase: true),
connectionId: connectionId
);
}
//
return result;
}
/// <summary>
/// count all exists Dtos ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<int> CountAsync(
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.CountAsync(
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// Check a Dto exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> IsExistsAsync(
TKey id,
bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve an Dto by it's Id ...
/// </summary>
/// <param name="id"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> GetAsync(
TKey id,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.GetAsync(
id: id,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve all exists Dtos ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<TDto>> GetAllAsync(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.GetAllAsync(
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find an Dto by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<TDto> FindOneAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.FindOneAsync(
predicate: predicate,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// find a collection of Dtos by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IEnumerable<TDto>> FindManyAsync(
Expression<Func<TEntity, bool>> predicate,
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.FindManyAsync(
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
/// <summary>
/// retrieve Dtos based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XQueryResult<TDto>> QueryAsync(
XQuery query,
bool ignoreSoftDeleteds = true,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await RepositoryService.QueryAsync(
query: query,
predicate: predicate,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return result;
}
#endregion
//
#region Hub Actions ...
/// <summary>
/// Send Custom Push Message ...
/// </summary>
/// <param name="action"></param>
/// <param name="payLoad"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task SendPush(
string action,
string payLoad,
string connectionId = null,
CancellationToken cancellationToken = default
)
{
//
var actions = new List<string>
{
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,
cancellationToken
);
}
catch { }
}
#endregion
}
}
+45 -7
View File
@@ -4,6 +4,7 @@ using xPushService.Interfaces;
using Microsoft.AspNetCore.SignalR;
using xPushService.Constants;
using xCommons.Extensions;
using System.Threading;
namespace xPushService.Base
{
@@ -28,20 +29,40 @@ namespace xPushService.Base
/// </summary>
/// <param name="offer"></param>
/// <param name="to"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Offer(string offer, string to)
public async Task Offer(
string offer,
string to,
CancellationToken cancellationToken = default
)
{
await Clients.Client(to).SendAsync(XWebRTCAction.Offer.GetStringValue(), offer);
//
await Clients.Client(to).SendAsync(
XWebRTCAction.Offer.GetStringValue(),
offer,
cancellationToken
);
}
/// <summary>
/// Sending WebRTC Answer to Specified Connection ...
/// </summary>
/// <param name="answer"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Answer(string answer)
public async Task Answer(
string answer,
CancellationToken cancellationToken = default
)
{
await Clients.All.SendAsync(XWebRTCAction.Answer.GetStringValue(), answer, Context.ConnectionId);
//
await Clients.All.SendAsync(
XWebRTCAction.Answer.GetStringValue(),
answer,
Context.ConnectionId,
cancellationToken
);
}
/// <summary>
@@ -49,18 +70,35 @@ namespace xPushService.Base
/// </summary>
/// <param name="candidate"></param>
/// <param name="to"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task Candidate(string candidate, string to)
public async Task Candidate(
string candidate,
string to,
CancellationToken cancellationToken = default
)
{
//
string actionName = XWebRTCAction.Candidate.GetStringValue();
if (!string.IsNullOrEmpty(to))
{
await Clients.Client(to).SendAsync(actionName, candidate, Context.ConnectionId);
//
await Clients.Client(to).SendAsync(
actionName,
candidate,
Context.ConnectionId,
cancellationToken
);
}
else
{
await Clients.All.SendAsync(actionName, candidate, Context.ConnectionId);
//
await Clients.All.SendAsync(
actionName,
candidate,
Context.ConnectionId,
cancellationToken
);
}
}
#endregion
-11
View File
@@ -1,11 +0,0 @@
using xModels.Base;
namespace xPushService.Base
{
public class XHubConnectionDto : XBaseDto
{
public string ConnectionId { get; set; }
public string UserId { get; set; }
public string Username { get; set; }
}
}