### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseDtoHub.cs 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 : XBaseHub, IXBaseDtoHub where TEntity : XBaseEntity where TDto : XBaseEntityDto { // #region Constructor ... protected XBaseDtoHub(ILogger logger) : base(logger) { } #endregion // #region Actions ... /// /// Notify a New Item added ... /// /// /// /// 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 ); } } /// /// Notify a New Item added ... /// /// /// /// 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 ); } } /// /// Notify Add Many Items ... /// /// /// /// public async Task AddMany( IEnumerable 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 ); } } /// /// Notify an Item Deleted ... /// /// /// /// 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 ); } } /// /// Notify Delete Many Items ... /// /// /// /// public async Task DeleteMany( IEnumerable 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 ); } } /// /// Notify an Item Updated ... /// /// /// /// 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 ); } } /// /// Notify Update Many Items ... /// /// /// /// public async Task UpdateMany( IEnumerable 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 } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseDtoProvider.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; 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 : IXBaseDtoProvider where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Properties ... public IHubContext Hub { get; } public IXIdentityProvider IdentityProvider { get; } public XDataServiceConfiguration DataConfiguration { get; } public IXBaseRepositoryService Service { get; } #endregion // #region Constructor ... protected XBaseDtoProvider( IHubContext hub, XDataServiceConfiguration dataConfiguration, IXBaseRepositoryService service, IXIdentityProvider identityProvider = null ) { // Hub = hub; Service = service; IdentityProvider = identityProvider; DataConfiguration = dataConfiguration; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// /// public virtual async Task 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; } /// /// Update an Item values ... /// /// /// /// /// /// /// public virtual async Task 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; } /// /// remove an Item by it's Id ... /// /// /// /// /// /// /// public virtual async Task 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; } /// /// count all exists Items ... /// /// /// /// public virtual async Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await Service.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// Check an Item exists or not ... /// /// /// /// /// public virtual async Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await Service.IsExistsAsync( id: id, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// public virtual async Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Service.GetAsync( id: id, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve all exists Items ... /// /// /// /// /// /// public virtual async Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Service.GetAllAsync( orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve all exists Dtos /// as Async Enumerable ... /// /// /// /// /// /// public virtual async IAsyncEnumerable GetAllAsAsyncEnumerable( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, [EnumeratorCancellation] CancellationToken cancellationToken = default ) { // var enumerable = Service.GetAllAsAsyncEnumerable( orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // await foreach (var dto in enumerable) { // if (cancellationToken.IsCancellationRequested) { yield break; } // yield return dto; } } /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// public virtual async Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Service.FindOneAsync( predicate: predicate, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// public virtual async Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Service.FindManyAsync( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// public virtual async Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> 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 ... /// /// Send Custom Push Message ... /// /// /// /// /// /// public async Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ) { // 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() && !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 } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseEntityHub.cs 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 : XBaseHub, IXBaseEntityHub where TEntity : XBaseEntity { // #region Constructor ... protected XBaseEntityHub(ILogger logger) : base(logger) { } #endregion // #region Actions ... /// /// Notify a New Entity added ... /// /// /// /// public async Task Add( TEntity entity, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.Add.GetStringValue(), entity.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify a New Entity added ... /// /// /// /// public async Task AddOrUpdate( TEntity entity, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.AddOrUpdate.GetStringValue(), entity.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify Add Many Entities ... /// /// /// /// public async Task AddMany( IEnumerable entities, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.AddOrUpdate.GetStringValue(), entities.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify an Entity Deleted ... /// /// /// /// public async Task Delete( TEntity entity, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.Delete.GetStringValue(), entity.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify Delete Many Entities ... /// /// /// /// public async Task DeleteMany( IEnumerable entities, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.DeleteMany.GetStringValue(), entities.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify an Entity Updated ... /// /// /// /// public async Task Update( TEntity entity, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.Update.GetStringValue(), entity.ToJSON(camelCase: true), connectionId, cancellationToken ); } } /// /// Notify Update Many Entities ... /// /// /// /// public async Task UpdateMany( IEnumerable entities, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // await Clients .AllExcept(connectionId) .SendAsync( XBaseEntityHubAction.UpdateMany.GetStringValue(), entities.ToJSON(camelCase: true), connectionId, cancellationToken ); } } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseEntityProvider.cs 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 : IXBaseEntityProvider where TEntity : XBaseEntity where THub : XBaseEntityHub { // #region Properties ... public IHubContext Hub { get; } public IXIdentityProvider IdentityProvider { get; } public IXBaseRepository Repository { get; } public XDataServiceConfiguration DataConfiguration { get; } #endregion // #region Constructor ... protected XBaseEntityProvider( IHubContext hub, IXBaseRepository repository, XDataServiceConfiguration dataConfiguration, IXIdentityProvider identityProvider = null ) { // Hub = hub; Repository = repository; IdentityProvider = identityProvider; DataConfiguration = dataConfiguration; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// /// public virtual async Task 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; } /// /// Update an Item values ... /// /// /// /// /// /// /// public virtual async Task 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; } /// /// remove an Item by it's Id ... /// /// /// /// /// /// /// public virtual async Task 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; } /// /// count all exists Items ... /// /// /// /// public virtual async Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await Repository.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// Check an Item exists or not ... /// /// /// /// /// public virtual async Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await Repository.IsExistsAsync( id: id, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// public virtual async Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Repository.GetAsync( id: id, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve all exists Items ... /// /// /// /// /// /// public virtual async Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Repository.GetAllAsync( orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// public virtual async Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Repository.FindOneAsync( predicate: predicate, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// public virtual async Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await Repository.FindManyAsync( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// public virtual async Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> 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 ... /// /// Send Custom Push Message ... /// /// /// /// /// /// public async Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ) { // 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() && !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 } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseHub.cs using System; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using xCommons.Extensions; using xPushService.Constants; using xPushService.Interfaces; namespace xPushService.Base { public abstract class XBaseHub : Hub, IXBaseHub { // #region Props ... protected readonly ILogger logger; #endregion // #region Constructor ... public XBaseHub( ILogger logger ) { this.logger = logger; } #endregion // #region Overrides ... public override async Task OnConnectedAsync() { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // // Notify Other Clients Which a new Connection Joins ... await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.NewConnection.GetStringValue(), connectionId); } // await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception exception) { // var connectionId = Context.ConnectionId; if (!connectionId.IsNullOrEmpty()) { // // Notify Other Clients Which a Connection Closed ... await Clients.AllExcept(connectionId).SendAsync(XBaseHubAction.ConnectionClosed.GetStringValue(), connectionId); } await base.OnDisconnectedAsync(exception); } #endregion // #region Actions ... public async Task SendCustomAction( string actionName, string payLoad, CancellationToken cancellationToken = default ) { // var connectionId = Context.ConnectionId; await Clients.AllExcept(connectionId).SendAsync( actionName, payLoad, connectionId, cancellationToken ); } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseProvider.cs 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 : IXBaseProvider where TEntity : XBaseEntity where TDto : XBaseEntityDto { // #region Props ... public IXIdentityProvider IdentityProvider { get; } public XDataServiceConfiguration DataConfiguration { get; } public IHubContext> Hub { get; } public IXBaseRepositoryService RepositoryService { get; } #endregion // #region Actions ... /// /// add a new Dto ... /// /// /// /// /// /// public async Task 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; } /// /// Update an Dto values ... /// /// /// /// /// /// /// public async Task 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; } /// /// remove an Dto by it's Id ... /// /// /// /// /// /// /// public async Task 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; } /// /// count all exists Dtos ... /// /// /// /// public async Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// Check a Dto exists or not ... /// /// /// /// /// public async Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.IsExistsAsync( id: id, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve an Dto by it's Id ... /// /// /// /// /// /// public async Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.GetAsync( id: id, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve all exists Dtos ... /// /// /// /// /// /// public async Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.GetAllAsync( orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// find an Dto by providing a Conditional Expression ... /// /// /// /// /// /// public async Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.FindOneAsync( predicate: predicate, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// find a collection of Dtos by proving a Conditional Expression ... /// /// /// /// /// /// /// public async Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await RepositoryService.FindManyAsync( predicate: predicate, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return result; } /// /// retrieve Dtos based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// public async Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> 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 ... /// /// Send Custom Push Message ... /// /// /// /// /// /// public async Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ) { // 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, cancellationToken ); } catch { } } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Base\XBaseWebRTCHub.cs using System.Threading.Tasks; using Microsoft.Extensions.Logging; using xPushService.Interfaces; using Microsoft.AspNetCore.SignalR; using xPushService.Constants; using xCommons.Extensions; using System.Threading; namespace xPushService.Base { public abstract class XBaseWebRTCHub : XBaseHub, IXBaseWebRTCHub { // #region Props ... #endregion // #region Constructor ... protected XBaseWebRTCHub( ILogger logger ) : base(logger) { } #endregion // #region WebRTCActions ... /// /// Sending WebRTC Offer To Specified Connection ... /// /// /// /// /// public async Task Offer( string offer, string to, CancellationToken cancellationToken = default ) { // await Clients.Client(to).SendAsync( XWebRTCAction.Offer.GetStringValue(), offer, cancellationToken ); } /// /// Sending WebRTC Answer to Specified Connection ... /// /// /// /// public async Task Answer( string answer, CancellationToken cancellationToken = default ) { // await Clients.All.SendAsync( XWebRTCAction.Answer.GetStringValue(), answer, Context.ConnectionId, cancellationToken ); } /// /// Sending WebRTC Candidate to Specified Connecton ... /// /// /// /// /// 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, cancellationToken ); } else { // await Clients.All.SendAsync( actionName, candidate, Context.ConnectionId, cancellationToken ); } } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Configurations\XPushServiceConfiguration.cs namespace xPushService.Configurations { public partial class XPushServiceConfiguration { /// /// Base route of WebSocket Server ... /// /// string public string BaseRoute { get; set; } /// /// determines log level of signalR ... /// /// public object ConnectionLogLevel { get; set; } /// /// when client disconnected it's automatically try to reconnect, this /// determines max number of try to connect ... /// /// public int PushConnectionMaxRetry { get; set; } /// /// add support for message protocol ... /// /// public bool AddSupportMessageProtocol { get; set; } /// /// the delay between two connection try .. /// /// public int PushConnectionReconnectDelay { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Constants\XPushAction.cs using xExceptions.Attributes; namespace xPushService.Constants { public enum XBaseHubAction { /// /// new Connection Join ... /// [StringValue("NewConnection")] NewConnection, /// /// an Exists Connection Closed ... /// [StringValue("ConnectionClosed")] ConnectionClosed, } /// /// All Actions in WebRTC Hubs ... /// public enum XWebRTCAction { // [StringValue("Offer")] Offer, [StringValue("Answer")] Answer, [StringValue("Candidate")] Candidate, } /// /// Provides All Actions Based on Entities ... /// public enum XBaseEntityHubAction { [StringValue("Add")] Add, [StringValue("AddOrUpdate")] AddOrUpdate, [StringValue("AddMany")] AddMany, [StringValue("Update")] Update, [StringValue("UpdateMany")] UpdateMany, [StringValue("Delete")] Delete, [StringValue("DeleteMany")] DeleteMany, } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Constants\XPushServiceConstants.cs namespace xPushService.Constants { public partial class XPushServiceConstants { public partial struct XConfigurationNodes { public const string XPushServiceConfiguration = "PushServiceConfiguration"; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseProvidedController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using xCommons.Configurations; using xCommons.Extensions; using xCommons.Providers; using xExceptions.Constants; using xIdentityService.Controllers; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; using xPushService.Interfaces; namespace xPushService.Controllers { [AllowAnonymous] public abstract class XBaseProvidedController : XBaseIdentityApiV1Controller, IXBaseProvidedController where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { private readonly IXBaseProvided provider; private readonly Func, IOrderedQueryable> defaultOrderBuilder; private readonly Func, IIncludableQueryable> defaultIncludeBuilder; protected XBaseProvidedController( ILogger> logger, XAppConfiguration appConfiguration, IXIdentityProvider identityProvider, XValidationProvider validationProvider, IXBaseProvided provider, Func, IOrderedQueryable> defaultOrderBuilder = null, Func, IIncludableQueryable> defaultIncludeBuilder = null ) : base( logger, appConfiguration, identityProvider, validationProvider ) { this.provider = provider; this.defaultOrderBuilder = defaultOrderBuilder; this.defaultIncludeBuilder = defaultIncludeBuilder; } // #region Retrieve ... /// /// Get Specified Item by ID ... /// /// /// /// /// [HttpGet("{id}")] public virtual async Task> Get( [FromRoute] TKey id, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotNull(id); // var result = await provider.Get( id: id, includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Get All Exists Items ... /// /// /// /// /// [HttpGet("")] public virtual async Task>> GetAll( [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await provider.GetAll( orderBuilder: !useDefaultOrders ? null : defaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Find an item by providing a Conditional Expression ... /// /// /// /// /// [HttpGet("Find/One")] public virtual async Task> FindOne( [FromRoute] string query, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotEmpty(query) .ValidateGroupAsync(); // var result = await provider.FindOne( includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken, predicate: x => x.PropValuesContains(query) ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Find a collection of Items by proving a Query Search ... /// /// /// /// /// /// [HttpGet("Find/Many")] public virtual async Task>> FindMany( [FromRoute] string query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotEmpty(query) .ValidateGroupAsync(); // var result = await provider.FindMany( orderBuilder: !useDefaultOrders ? null : defaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken, predicate: x => x.PropValuesContains(query) ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// [HttpGet("Query")] public virtual async Task>> Query( [FromQuery] XQuery query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(query) .ValidateGroupAsync(); // var result = await provider.Query( query: query, predicate: null, orderBuilder: !useDefaultOrders ? null : defaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Retrieve Owned Items based on XQuery Pagination structure ... /// /// /// /// /// /// [HttpGet("Query/Owned")] public virtual async Task>> QueryOwned( [FromQuery] XQuery query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(query) .ValidateGroupAsync(); // var userInfo = await GetUserInfo(); // var result = await provider.QueryOwned( query: query, predicate: null, userInfo: userInfo, orderBuilder: !useDefaultOrders ? null : defaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : defaultIncludeBuilder, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } #endregion // #region Add/Update/Remove ... /// /// Add an item ... /// /// /// /// [HttpPost("")] public virtual async Task> Add( [FromBody] TDto item, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(item) .ValidateGroupAsync(); // var userInfo = await GetUserInfo(); var connectionId = GetConnectionId(); // var result = await provider.Add( item: item, userInfo: userInfo, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Update an item values ... /// /// /// /// /// [HttpPut("{id}")] public virtual async Task> Update( [FromRoute] TKey id, [FromBody] TDto item, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(id) .AddNotNull(item) .ValidateGroupAsync(); // var userInfo = await GetUserInfo(); var connectionId = GetConnectionId(); // var result = await provider.Update( id: id, item: item, userInfo: userInfo, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Remove an Item ... /// /// /// /// [HttpDelete("{id}")] public virtual async Task> Remove( [FromRoute] TKey id, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(id) .ValidateGroupAsync(); // var userInfo = await GetUserInfo(); var connectionId = GetConnectionId(); // var result = await provider.Remove( id: id, userInfo: userInfo, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseRepositoryProviderController.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using xCommons.Configurations; using xCommons.Extensions; using xCommons.Providers; using xDataService.Extensions; using xExceptions.Constants; using xIdentityService.Controllers; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; using xPushService.Interfaces; namespace xPushService.Controllers { [AllowAnonymous] public abstract class XBaseRepositoryProviderController : XBaseIdentityApiV1Controller, IXBaseRepositoryProviderController where TEntity : XBaseEntity where THub : XBaseEntityHub { // #region Properties ... public IXBaseEntityProvider Provider { get; } public Func, IOrderedQueryable> DefaultOrderBuilder { get; } public Func, IIncludableQueryable> DefaultIncludeBuilder { get; } #endregion protected XBaseRepositoryProviderController( ILogger logger, XAppConfiguration appConfiguration, IXIdentityProvider identityProvider, XValidationProvider validationProvider, IXBaseEntityProvider provider, Func, IOrderedQueryable> defaultOrderBuilder = null, Func, IIncludableQueryable> defaultIncludeBuilder = null ) : base( logger: logger, appConfiguration: appConfiguration, identityProvider: identityProvider, validationProvider: validationProvider ) { // Provider = provider; DefaultOrderBuilder = defaultOrderBuilder; DefaultIncludeBuilder = defaultIncludeBuilder; } // #region Actions ... /// /// add a new Item ... /// /// /// /// /// [HttpPost] public virtual async Task> Add( [FromBody] TEntity item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotNull(item); // var connectionId = GetConnectionId(); // var result = await Provider.AddAsync( item: item, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Update an Item values ... /// /// /// /// /// /// [HttpPut("{id}")] public virtual async Task> Update( [FromRoute] TKey id, [FromBody] TEntity item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotNull(item); // var connectionId = GetConnectionId(); // var result = await Provider.UpdateAsync( id: id, item: item, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// remove an Item by it's Id ... /// /// /// /// /// /// [HttpDelete("{id}")] public virtual async Task> Remove( [FromRoute] TKey id, [FromQuery] bool softDelete = true, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var connectionId = GetConnectionId(); // var result = await Provider.RemoveAsync( id: id, softDelete: softDelete, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Check an Item exists or not ... /// /// /// /// /// [HttpGet("{id}/[action]")] public virtual async Task> IsExists( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.IsExistsAsync( id: id, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// count all exists Items ... /// /// /// /// [HttpGet("Count")] public virtual async Task> Count( [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// [HttpGet("{id}")] public virtual async Task> Get( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.GetAsync( id: id, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// retrieve all exists Items ... /// /// /// /// /// /// [HttpGet] public virtual async Task>> GetAll( [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.GetAllAsync( orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// [HttpGet("FindOne")] public virtual async Task> FindOne( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotEmpty(query); // Expression> predicate = x => x.PropValuesContains(query); var result = await Provider.FindOneAsync( predicate: predicate, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// find a collection of Items by proving a Query Search ... /// /// /// /// /// /// /// [HttpGet("FindMany")] public virtual async Task>> FindMany( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotEmpty(query); // Expression> predicate = x => x.PropValuesContains(query); var result = await Provider.FindManyAsync( predicate: predicate, orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// [HttpGet("Query")] public virtual async Task>> Query( [FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // // Normalize ... if (query.IsNullOrDefault()) { query = query.NormalizeQuery(Provider.DataConfiguration); } // var result = await Provider.QueryAsync( query: query, predicate: null, orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } #endregion // #region NonActions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// [NonAction] public virtual async Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ) { // await Provider.SendPush( action: action, payLoad: payLoad, connectionId: connectionId, cancellationToken: cancellationToken ); } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Controllers\XBaseServiceProviderController.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using xCommons.Configurations; using xCommons.Extensions; using xCommons.Providers; using xDataService.Extensions; using xExceptions.Constants; using xIdentityService.Controllers; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; using xPushService.Interfaces; namespace xPushService.Controllers { [AllowAnonymous] public abstract class XBaseServiceProviderController : XBaseIdentityApiV1Controller, IXBaseServiceProviderController where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Properties ... public IXBaseDtoProvider Provider { get; } public Func, IOrderedQueryable> DefaultOrderBuilder { get; } public Func, IIncludableQueryable> DefaultIncludeBuilder { get; } #endregion // #region Constructor ... public XBaseServiceProviderController( ILogger logger, XAppConfiguration appConfiguration, IXIdentityProvider identityProvider, XValidationProvider validationProvider, IXBaseDtoProvider provider, Func, IOrderedQueryable> defaultOrderBuilder = null, Func, IIncludableQueryable> defaultIncludeBuilder = null ) : base( logger, appConfiguration, identityProvider, validationProvider ) { // Provider = provider; DefaultOrderBuilder = defaultOrderBuilder; DefaultIncludeBuilder = defaultIncludeBuilder; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// [HttpPost] public virtual async Task> Add( [FromBody] TDto item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotNull(item); // var connectionId = GetConnectionId(); // var result = await Provider.AddAsync( item: item, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Update an Item values ... /// /// /// /// /// /// [HttpPut("{id}")] public virtual async Task> Update( [FromRoute] TKey id, [FromBody] TDto item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotNull(item); // var connectionId = GetConnectionId(); // var result = await Provider.UpdateAsync( id: id, item: item, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// remove an Item by it's Id ... /// /// /// /// /// /// [HttpDelete("{id}")] public virtual async Task> Remove( [FromRoute] TKey id, [FromQuery] bool softDelete = true, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var connectionId = GetConnectionId(); // var result = await Provider.RemoveAsync( id: id, softDelete: softDelete, saveChanges: saveChanges, connectionId: connectionId, cancellationToken: cancellationToken ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Check an Item exists or not ... /// /// /// /// /// [HttpGet("{id}/[action]")] public virtual async Task> IsExists( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.IsExistsAsync( id: id, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// count all exists Items ... /// /// /// /// [HttpGet("Count")] public virtual async Task> Count( [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.CountAsync( cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// [HttpGet("{id}")] public virtual async Task> Get( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.GetAsync( id: id, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// retrieve all exists Items ... /// /// /// /// /// /// [HttpGet] public virtual async Task>> GetAll( [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // var result = await Provider.GetAllAsync( orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// [HttpGet("FindOne")] public virtual async Task> FindOne( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotEmpty(query); // Expression> predicate = x => x.PropValuesContains(query); var result = await Provider.FindOneAsync( predicate: predicate, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// [HttpGet("FindMany")] public virtual async Task>> FindMany( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } ValidationProvider.NotEmpty(query); // Expression> predicate = x => x.PropValuesContains(query); var result = await Provider.FindManyAsync( predicate: predicate, orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// [HttpGet("Query")] public virtual async Task>> Query( [FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ) { // try { // // Validate ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } // // Normalize ... if (query.IsNullOrDefault()) { query = query.NormalizeQuery(Provider.DataConfiguration); } // var result = await Provider.QueryAsync( query: query, predicate: null, orderBuilder: !useDefaultOrders ? null : DefaultOrderBuilder, includeBuilder: !useDefaultIncludes ? null : DefaultIncludeBuilder, cancellationToken: cancellationToken, ignoreSoftDeleteds: ignoreSoftDeleteds ); // return Ok(result.ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } #endregion // #region NonActions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// [NonAction] public virtual async Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ) { // await Provider.SendPush( action: action, payLoad: payLoad, connectionId: connectionId, cancellationToken: cancellationToken ); } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\DI\XDIHelperExtension.cs using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using xCommons.Extensions; using xExceptions.Constants; using xPushService.Configurations; using xPushService.Constants; using xPushService.Helpers; using xPushService.Providers; namespace xPushService.DI { public static partial class XDIHelperExtension { /// /// Extract Module Configuration from provided IConfiguration /// /// /// an instance of XPushServiceConfiguration public static XPushServiceConfiguration GetXPushServiceConfiguration(this IConfiguration config) { // var xPushConfigSection = config.GetSection(XPushServiceConstants.XConfigurationNodes.XPushServiceConfiguration); return xPushConfigSection.Get(); } /// /// Register XPushServiceHelper ... /// /// /// public static void AddXPushServiceHelper( this IServiceCollection services, XPushServiceHelper helper ) { // // Validate Args ... if (helper.IsNull()) { // Log("AddXPushServiceHelper failed, helper not provided ..."); throw XException.InvalidArgs.ToException(); } // // Register Helper ... services.AddSingleton(helper); } /// /// Register Module Provided Service on DI /// /// /// /// public static void AddXPushService( this IServiceCollection services, IConfiguration config, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // AddPushService( services, config.GetXPushServiceConfiguration(), lifeTime ); } /// /// Register Module Provided Service on DI /// /// /// /// public static void AddXPushService( this IServiceCollection services, XPushServiceConfiguration config, ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // AddPushService( services, config, lifeTime ); } /// /// Use Module Middlewares on Application Builder /// /// /// public static void UseXPushService( this IApplicationBuilder app, XPushServiceHelper helper ) { // // Validate Args ... var isHelperExists = !helper.IsNull(); if (!isHelperExists) { // Log("AddXPushServiceHelper failed, helper not provided ..."); throw XException.InvalidArgs.ToException(); } // // Create an Scope for Accessing Registered Services ... using (var scope = app.ApplicationServices.CreateScope()) { // // try to Retrieve Configuration .... var config = scope.ServiceProvider.GetService(); if ( config.IsNull() || config.BaseRoute.IsNullOrEmpty() || config.BaseRoute.Trim().IsNullOrEmpty() ) { // Log("AddXPushServiceHelper failed, Configuration not provided ..."); throw XException.InvalidConfiguration.ToException(); } // #region Normalize Routes ... // // Base Reoute ... config.BaseRoute = config.BaseRoute.ToNormalString(); if (!config.BaseRoute.StartsWith("/")) { config.BaseRoute = "/" + config.BaseRoute; } #endregion // // add XPushService Hub to Helper ... // var hubRoutes = new List(); // // Try to Register Hubs ... // // Use SignalR in App ... app.UseSignalR(routes => { // helper.GetHubs().ForEach(hubDescriptor => { // var hubRoute = config.BaseRoute + "/" + hubDescriptor.Route; hubRoutes.Add(hubRoute); // try { // Type routesType = routes.GetType(); MethodInfo mapHubMethod = routesType .GetMethods() .SingleOrDefault(m => m.Name == "MapHub" && m.GetParameters().Length == 1 ); if (mapHubMethod.IsNull()) { throw XException.ActionFailed.ToException(); } // object[] genericMapHubMethodArgs = { new PathString(hubRoute) }; MethodInfo genericMapHubMethod = mapHubMethod.MakeGenericMethod(hubDescriptor.Hub); genericMapHubMethod.Invoke(routes, genericMapHubMethodArgs); // Log($"Register {hubDescriptor.Hub} Hub: {hubRoute}"); } catch { throw; } }); }); } } // #region Private ... /// /// a LogTag for XPushService ... /// private static string XLogTag = "XPushService"; /// /// print a log in Console ... /// /// private static void Log(string message) { Console.WriteLine($"{XLogTag} => {message}"); } /// /// Register Push Service ... /// /// /// /// private static void AddPushService( IServiceCollection services, XPushServiceConfiguration config, ServiceLifetime lifeTime ) { // #region Validate Args ... // var exception = XException.InvalidArgs.ToException(); ; // // Services ... var isServicesExists = !services.IsNull(); if (!isServicesExists) { // Log("AddXPushServiceHelper failed, services not provided ..."); throw exception; } // // Config ... var isConfigExists = !config.IsNull(); if (!isConfigExists) { // Log("AddXPushServiceHelper failed, configuration not provided ..."); throw exception; } // // Lifetime ... var isLifetimeExists = !lifeTime.IsNull(); if (!isLifetimeExists) { // Log("AddXPushServiceHelper failed, lifetime not provided ..."); throw exception; } #endregion // // Register XPushService Configuration ... services.AddSingleton(config); // // Register SignalR ... var builder = services.AddSignalR(options => { options.KeepAliveInterval = TimeSpan.FromSeconds(10); options.ClientTimeoutInterval = TimeSpan.FromSeconds(10); }); // // Add NewtonSoftJson Protocol ... builder.AddNewtonsoftJsonProtocol(x => { x.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; x.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // // Register XPushServiceUserNameProvider ... services.AddSingleton(); // // add Message Protocol Support ... if (config.AddSupportMessageProtocol) { builder.AddMessagePackProtocol(); } } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Extensions\ClaimsPrincipalExtensions.cs using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.SignalR; using xCommons.Constants; using xCommons.Extensions; using xCommons.Helpers; using xIdentityModels.Constants; using xPushService.Models; namespace xPushService.Extensions { public static class ClaimsPrincipalExtensions { /// /// Generate User Info based on HubCallerContext ... /// /// /// public static XHubUserInfo GetUserInfo(this HubCallerContext source) { // XHubUserInfo result = null; // if (source.IsNull() || source.User.IsNull() || !source.User.Claims.HasChild()) { return result; } // result = new XHubUserInfo { UserId = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserId)?.Value ?? "", UserName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.UserName)?.Value ?? "", FirstName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.FirstName)?.Value ?? "", LastName = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.LastName)?.Value ?? "", Picture = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Picture)?.Value ?? "", Email = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Email)?.Value ?? null, PhoneNumber = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumber)?.Value ?? null, }; // #region Handle Gender ... var genders = ObjectHelper.ToEnumerableKeys(); var genderStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.Gender).Value ?? null; if (genderStr.IsNullOrEmpty()) { result.Gender = XGender.Male; } else { result.Gender = genderStr.GetValue(); } #endregion // #region Handle IsBanned ... var isBannedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsBanned).Value ?? null; if (isBannedStr.IsNullOrEmpty()) { result.IsBanned = false; } else { // var isBanned = false; Boolean.TryParse(isBannedStr, out isBanned); // result.IsBanned = isBanned; } #endregion // #region Handle IsEnabled ... var isEnabledStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.IsEnabled).Value ?? null; if (isEnabledStr.IsNullOrEmpty()) { result.IsEnabled = false; } else { // var isEnabled = false; Boolean.TryParse(isEnabledStr, out isEnabled); // result.IsEnabled = isEnabled; } #endregion // #region Handle Email Confirmed ... var emailConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.EmailVerified).Value ?? null; if (emailConfirmedStr.IsNullOrEmpty()) { result.EmailConfirmed = false; } else { // var emailConfirmed = false; Boolean.TryParse(emailConfirmedStr, out emailConfirmed); // result.EmailConfirmed = emailConfirmed; } #endregion // #region Handle PhoneNumber Confirmed ... var phoneNumberConfirmedStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.PhoneNumberVerified).Value ?? null; if (phoneNumberConfirmedStr.IsNullOrEmpty()) { result.PhoneNumberConfirmed = false; } else { // var phoneNumberConfirmed = false; Boolean.TryParse(phoneNumberConfirmedStr, out phoneNumberConfirmed); // result.PhoneNumberConfirmed = phoneNumberConfirmed; } #endregion // #region Handle ExpiredOn ... var expiredOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.ExpiredOn).Value ?? null; if (expiredOnStr.IsNullOrEmpty()) { result.ExpiredOn = null; } else { // long expiredOn = 0; long.TryParse(expiredOnStr, out expiredOn); // result.ExpiredOn = expiredOn; } #endregion // #region Handle AuthenticatedOn ... var authenticatedOnStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.AuthenticatedOn).Value ?? null; if (authenticatedOnStr.IsNullOrEmpty()) { result.AuthenticatedOn = null; } else { // long authenticatedOn = 0; long.TryParse(authenticatedOnStr, out authenticatedOn); // result.AuthenticatedOn = authenticatedOn; } #endregion // #region Handle BrithDate ... var brithDateStr = source.User.Claims.FirstOrDefault(c => c.Type == XCustomClaims.BrithDate)?.Value ?? ""; if (brithDateStr.IsNullOrEmpty()) { // BrithDate = null; } else { // DateTime bDate; DateTime.TryParse(brithDateStr, out bDate); // result.BrithDate = bDate; } #endregion // result.Issuers = source.User.Claims.Where(c => c.Type == XCustomClaims.Issuer)? .Select(c => c.Value) ?? new HashSet(); result.Audiences = source.User.Claims.Where(c => c.Type == XCustomClaims.Audience)? .Select(c => c.Value) ?? new HashSet(); result.ClientIds = source.User.Claims.Where(c => c.Type == XCustomClaims.ClientId)? .Select(c => c.Value) ?? new HashSet(); result.Scopes = source.User.Claims.Where(c => c.Type == XCustomClaims.Scope)? .Select(c => c.Value) ?? new HashSet(); result.Roles = source.User.Claims.Where(c => c.Type == XCustomClaims.Role)? .Select(c => c.Value) ?? new HashSet(); // return result; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Helpers\XPushServiceHelper.cs using System.Collections.Generic; using System.Linq; using xCommons.Extensions; using xExceptions.Constants; using xPushService.Base; using xPushService.Models; namespace xPushService.Helpers { public class XPushServiceHelper { /// /// a collection of Hubs for Registring ... /// /// private List hubs = new List (); /// /// add specified hub to provided hubs for registration ... /// /// /// public void AddHub (string route) where TXHub : XBaseHub { // #region Validate Args ... // // check route not null ... if ( route.IsNullOrEmpty () || route.Trim ().IsNullOrEmpty () ) { throw XException.InvalidArgs.ToException (); } // // Normalize Route ... route = route.ToNormalString (); // // check route and hub must be unique ... var isRouteExists = hubs.Any (hd => hd.Route == route); var isHubExists = hubs.Any (hd => hd.Hub == typeof (TXHub)); if ( isHubExists || isRouteExists ) { throw XException.Duplicate.ToException (); } #endregion // // Add Provided Hub to List ... hubs.Add (new XHubDescriptor { Route = route, Hub = typeof (TXHub) }); } /// /// remove an specific hub from provided list ... /// /// public void RemoveHub () where TXHub : XBaseHub { // var existsHubDescriptor = hubs.SingleOrDefault (hd => hd.Hub == typeof (TXHub)); if (!existsHubDescriptor.IsNull ()) { hubs.Remove (existsHubDescriptor); } } /// /// retrieve provided hubs count ... /// /// public int Count () { return hubs.Count; } /// /// retrieve all provided hubs for registration ... /// /// public List GetHubs () { return hubs; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseDtoHub.cs using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using xModels.Base; namespace xPushService.Interfaces { public interface IXBaseDtoHub where TEntity : XBaseEntity where TDto : XBaseEntityDto { /// /// Notify a New Item added ... /// /// /// /// Task Add( TDto item, CancellationToken cancellationToken = default ); /// /// Notify a New Item added ... /// /// /// /// Task AddOrUpdate( TDto item, CancellationToken cancellationToken = default ); /// /// Notify Add Many Items ... /// /// /// /// Task AddMany( IEnumerable items, CancellationToken cancellationToken = default ); /// /// Notify an Item Deleted ... /// /// /// /// Task Delete( TDto item, CancellationToken cancellationToken = default ); /// /// Notify Delete Many Items ... /// /// /// /// Task DeleteMany( IEnumerable items, CancellationToken cancellationToken = default ); /// /// Notify an Item Updated ... /// /// /// /// Task Update( TDto item, CancellationToken cancellationToken = default ); /// /// Notify Update Many Items ... /// /// /// /// Task UpdateMany( IEnumerable items, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseDtoProvider.cs 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 xDataService.Configuration; using xDataService.Interfaces; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { public interface IXBaseDtoProvider where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Props ... IHubContext Hub { get; } IXIdentityProvider IdentityProvider { get; } XDataServiceConfiguration DataConfiguration { get; } IXBaseRepositoryService Service { get; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// /// Task AddAsync( TDto item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// Update an Item values ... /// /// /// /// /// /// /// Task UpdateAsync( TKey id, TDto item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// remove an Item by it's Id ... /// /// /// /// /// /// /// Task RemoveAsync( TKey id, bool softDelete = true, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// count all exists Items ... /// /// /// /// Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// Check an Item exists or not ... /// /// /// /// /// Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve all exists Items ... /// /// /// /// /// /// Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve all exists Dtos /// as Async Enumerable ... /// /// /// /// /// /// IAsyncEnumerable GetAllAsAsyncEnumerable( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); #endregion // #region Hub Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseEntityHub.cs using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using xModels.Base; namespace xPushService.Interfaces { public interface IXBaseEntityHub where TEntity : XBaseEntity { /// /// Notify a New Entity added ... /// /// /// /// Task Add( TEntity entity, CancellationToken cancellationToken = default ); /// /// Notify a New Entity added ... /// /// /// /// Task AddOrUpdate( TEntity entity, CancellationToken cancellationToken = default ); /// /// Notify Add Many Entities ... /// /// /// /// Task AddMany( IEnumerable entities, CancellationToken cancellationToken = default ); /// /// Notify an Entity Deleted ... /// /// /// /// Task Delete( TEntity entity, CancellationToken cancellationToken = default ); /// /// Notify Delete Many Entities ... /// /// /// /// Task DeleteMany( IEnumerable entities, CancellationToken cancellationToken = default ); /// /// Notify an Entity Updated ... /// /// /// /// Task Update( TEntity entity, CancellationToken cancellationToken = default ); /// /// Notify Update Many Entities ... /// /// /// /// Task UpdateMany( IEnumerable entities, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseEntityProvider.cs 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 xDataService.Configuration; using xDataService.Interfaces; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { /// /// a Provider is a way to Manipulate Data using Repository or Services and Contains Push /// notifications ability ... /// /// /// public interface IXBaseEntityProvider where TEntity : XBaseEntity where THub : XBaseEntityHub { // #region Props ... IHubContext Hub { get; } IXIdentityProvider IdentityProvider { get; } IXBaseRepository Repository { get; } XDataServiceConfiguration DataConfiguration { get; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// /// Task AddAsync( TEntity item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// Update an Item values ... /// /// /// /// /// /// /// Task UpdateAsync( TKey id, TEntity item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// remove an Item by it's Id ... /// /// /// /// /// /// /// Task RemoveAsync( TKey id, bool softDelete = true, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// count all exists Items ... /// /// /// /// Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// Check an Item exists or not ... /// /// /// /// /// Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve all exists Items ... /// /// /// /// /// /// Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); #endregion // #region Hub Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseHub.cs using System.Threading; using System.Threading.Tasks; namespace xPushService.Interfaces { public interface IXBaseHub { Task SendCustomAction( string actionName, string payLoad, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvided.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; using xIdentityModels.Models; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { /// /// a Provided Service Used for Providing Data Based on Validations of Users ... /// /// /// /// /// public interface IXBaseProvided where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { /// /// Get Specified Item by ID ... /// /// /// /// /// Task Get( TKey id, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Get All Exists Items ... /// /// /// /// /// Task> GetAll( Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Find an item by providing a Conditional Expression ... /// /// /// /// /// Task FindOne( Expression> predicate, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// Task> FindMany( Expression> predicate, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// Task> Query( XQuery query, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Retrieve Owned Items based on XQuery Pagination structure ... /// if supported ... /// /// /// /// /// /// /// /// Task> QueryOwned( XQuery query, XUserClaimsInfoDto userInfo = null, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// Add an item values ... /// /// /// /// /// /// Task Add( TDto item, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ); /// /// Update an item values ... /// /// /// /// /// /// /// Task Update( TKey id, TDto item, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ); /// /// remove an Item ... /// /// /// /// /// /// Task Remove( TKey id, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ); /// /// count all exists Items ... /// /// /// Task Count( CancellationToken cancellationToken = default ); /// /// Check an Item exists or not ... /// /// /// /// Task IsExists( TKey id, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvidedController.cs using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { /// /// a Provided Controller Used for Providing a Provided Service Actions ... /// /// /// /// /// public interface IXBaseProvidedController where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Retrieve ... /// /// Get Specified Item by ID ... /// /// /// /// /// [HttpGet("{id}")] Task> Get( [FromRoute] TKey id, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// Get All Exists Items ... /// /// /// /// /// [HttpGet("")] Task>> GetAll( [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// Find an item by providing a Conditional Expression ... /// /// /// /// /// [HttpGet("Find/One")] Task> FindOne( [FromQuery] string query, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// Find a collection of Items by proving a Query Search ... /// /// /// /// /// /// [HttpGet("Find/Many")] Task>> FindMany( [FromQuery] string query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// Retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// [HttpGet("Query")] Task>> Query( [FromQuery] XQuery query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// Retrieve Owned Items based on XQuery Pagination structure ... /// /// /// /// /// /// [HttpGet("Query/Owned")] Task>> QueryOwned( [FromQuery] XQuery query, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); #endregion // #region Add/Update/Remove ... /// /// Add an item ... /// /// /// /// [HttpPost("")] Task> Add( [FromBody] TDto item, CancellationToken cancellationToken = default ); /// /// Update an item values ... /// /// /// /// /// [HttpPut("{id}")] Task> Update( [FromRoute] TKey id, [FromBody] TDto item, CancellationToken cancellationToken = default ); /// /// Remove an Item ... /// /// /// /// [HttpDelete("{id}")] Task> Remove( [FromRoute] TKey id, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseProvider.cs 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 xDataService.Configuration; using xDataService.Interfaces; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { /// /// a Provider is a way to Manipulate Data using Repository or Services and Contains Push /// notifications ability ... /// /// /// /// public interface IXBaseProvider where TEntity : XBaseEntity where TDto : XBaseEntityDto { // #region Props ... // IXIdentityProvider IdentityProvider { get; } XDataServiceConfiguration DataConfiguration { get; } IHubContext> Hub { get; } IXBaseRepositoryService RepositoryService { get; } #endregion // #region Actions ... /// /// add a new Dto ... /// /// /// /// /// /// Task AddAsync( TDto item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// Update an Dto values ... /// /// /// /// /// /// /// Task UpdateAsync( TKey id, TDto item, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// remove an Dto by it's Id ... /// /// /// /// /// /// /// Task RemoveAsync( TKey id, bool softDelete = true, bool saveChanges = true, string connectionId = null, CancellationToken cancellationToken = default ); /// /// count all exists Dtos ... /// /// /// /// Task CountAsync( bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// Check a Dto exists or not ... /// /// /// /// /// Task IsExistsAsync( TKey id, bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// retrieve an Dto by it's Id ... /// /// /// /// /// /// Task GetAsync( TKey id, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve all exists Dtos ... /// /// /// /// /// /// Task> GetAllAsync( bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find an Dto by providing a Conditional Expression ... /// /// /// /// /// /// Task FindOneAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// find a collection of Dtos by proving a Conditional Expression ... /// /// /// /// /// /// /// Task> FindManyAsync( Expression> predicate, bool ignoreSoftDeleteds = true, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); /// /// retrieve Dtos based on XQuery Pagination structure ... /// /// /// /// /// /// /// /// Task> QueryAsync( XQuery query, bool ignoreSoftDeleteds = true, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ); #endregion // #region Hub Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseRepositoryProviderController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Query; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { public interface IXBaseRepositoryProviderController where TEntity : XBaseEntity where THub : XBaseEntityHub { // #region Properties ... IXBaseEntityProvider Provider { get; } Func, IOrderedQueryable> DefaultOrderBuilder { get; } Func, IIncludableQueryable> DefaultIncludeBuilder { get; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// [HttpPost] Task> Add( [FromBody] TEntity item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// Update an Item values ... /// /// /// /// /// /// [HttpPut("{id}")] Task> Update( [FromRoute] TKey id, [FromBody] TEntity item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// remove an Item by it's Id ... /// /// /// /// /// /// [HttpDelete("{id}")] Task> Remove( [FromRoute] TKey id, [FromQuery] bool softDelete = true, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// Check an Item exists or not ... /// /// /// /// /// [HttpGet("{id}/[action]")] Task> IsExists( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// count all exists Items ... /// /// /// /// [HttpGet("Count")] Task> Count( [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// [HttpGet("{id}")] Task> Get( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// retrieve all exists Items ... /// /// /// /// /// /// [HttpGet] Task>> GetAll( [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// [HttpGet("FindOne")] Task> FindOne( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// [HttpGet("FindMany")] Task>> FindMany( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// [HttpGet("Query")] Task>> Query( [FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); #endregion // #region Non Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// [NonAction] Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseServiceProviderController.cs using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Query; using xModels.Base; using xModels.Dtos; using xPushService.Base; namespace xPushService.Interfaces { public interface IXBaseServiceProviderController where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Properties ... IXBaseDtoProvider Provider { get; } Func, IOrderedQueryable> DefaultOrderBuilder { get; } Func, IIncludableQueryable> DefaultIncludeBuilder { get; } #endregion // #region Actions ... /// /// add a new Item ... /// /// /// /// /// [HttpPost] Task> Add( [FromBody] TDto item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// Update an Item values ... /// /// /// /// /// /// [HttpPut("{id}")] Task> Update( [FromRoute] TKey id, [FromBody] TDto item, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// remove an Item by it's Id ... /// /// /// /// /// /// [HttpDelete("{id}")] Task> Remove( [FromRoute] TKey id, [FromQuery] bool softDelete = true, [FromQuery] bool saveChanges = true, CancellationToken cancellationToken = default ); /// /// Check an Item exists or not ... /// /// /// /// /// [HttpGet("{id}/[action]")] Task> IsExists( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// count all exists Items ... /// /// /// /// [HttpGet("Count")] Task> Count( [FromQuery] bool ignoreSoftDeleteds = true, CancellationToken cancellationToken = default ); /// /// retrieve an Item by it's Id ... /// /// /// /// /// /// [HttpGet("{id}")] Task> Get( [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// retrieve all exists Items ... /// /// /// /// /// /// [HttpGet] Task>> GetAll( [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// find an Item by providing a Conditional Expression ... /// /// /// /// /// /// [HttpGet("FindOne")] Task> FindOne( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// /// [HttpGet("FindMany")] Task>> FindMany( [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// [HttpGet("Query")] Task>> Query( [FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool useDefaultOrders = false, [FromQuery] bool useDefaultIncludes = false, CancellationToken cancellationToken = default ); #endregion // #region Non Actions ... /// /// Send Custom Push Message ... /// /// /// /// /// /// [NonAction] Task SendPush( string action, string payLoad, string connectionId = null, CancellationToken cancellationToken = default ); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXBaseWebRTCHub.cs using System.Threading; using System.Threading.Tasks; namespace xPushService.Interfaces { public interface IXBaseWebRTCHub : IXBaseHub { /// /// Sending WebRTC Offer To Specified Connection ... /// /// /// /// /// Task Offer( string offer, string to, CancellationToken cancellationToken = default ); /// /// Sending WebRTC Answer to Specified Connection ... /// /// /// /// Task Answer( string answer, CancellationToken cancellationToken = default ); /// /// Sending WebRTC Candidate to Specified Connecton ... /// /// /// /// /// Task Candidate( string candidate, string to, CancellationToken cancellationToken = default ); } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Interfaces\IXHubContextFactory.cs using Microsoft.AspNetCore.SignalR; namespace xPushService.Interfaces { public interface IXHubContextFactory { IHubContext Create() where THub : Hub; } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubConnectionDto.cs using xModels.Base; namespace xPushService.Models { public class XHubConnectionDto : XBaseDto { public string ConnectionId { get; set; } public string UserId { get; set; } public string Username { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubDescriptor.cs using System; namespace xPushService.Models { /// /// Describe a Hub to Register ... /// public class XHubDescriptor { /// /// Specified the Hub Route ... /// /// public string Route { get; set; } /// /// Specified the Hub Class Type ... /// /// public Type Hub { get; set; } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Models\XHubUserInfo.cs using xModels.Base; using xIdentityModels.Constants; using System; using System.Collections.Generic; namespace xPushService.Models { public class XHubUserInfo : XBaseDto { // #region Properties ... public string UserId { get; set; } public string UserName { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Picture { get; set; } public string Email { get; set; } public string PhoneNumber { get; set; } public XGender Gender { get; set; } public bool IsBanned { get; set; } public bool IsEnabled { get; set; } public bool EmailConfirmed { get; set; } public bool PhoneNumberConfirmed { get; set; } public long? ExpiredOn { get; set; } public long? AuthenticatedOn { get; set; } public DateTime? BrithDate { get; set; } public IEnumerable Issuers { get; set; } = new HashSet(); public IEnumerable Audiences { get; set; } = new HashSet(); public IEnumerable ClientIds { get; set; } = new HashSet(); public IEnumerable Scopes { get; set; } = new HashSet(); public IEnumerable Roles { get; set; } = new HashSet(); #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XBaseProvided.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Query; using xCommons.Extensions; using xExceptions.Constants; using xIdentityModels.Extensions; using xIdentityModels.Models; using xModels.Base; using xModels.Dtos; using xPushService.Base; using xPushService.Interfaces; namespace xPushService.Providers { /// /// a Provided Service Used for Providing Data Based on Validations of Users ... /// /// /// /// /// public abstract class XBaseProvided : IXBaseProvided where TEntity : XBaseEntity where TDto : XBaseEntityDto where THub : XBaseDtoHub { // #region Props ... private readonly string[] permittedRoles; private readonly IXBaseDtoProvider provider; #endregion // #region Constructor ... protected XBaseProvided( IXBaseDtoProvider provider, string[] permittedRoles = null ) { this.provider = provider; this.permittedRoles = permittedRoles; } #endregion /// /// Check an Items is Owned for User or not ... /// /// /// /// public abstract bool IsOwned( TDto item, XUserClaimsInfoDto userInfo ); public abstract bool IsOwned( TEntity item, XUserClaimsInfoDto userInfo ); /// /// Check User Has Permission for Manipulate Data or not ... /// /// /// public bool HasPermision( XUserClaimsInfoDto userInfo ) { // var result = !permittedRoles.HasChild() || (!userInfo.IsNullOrDefault() && userInfo.HasAccess(permittedRoles)); // return result; } // #region Provided Actions ... /// /// Get Specified Item by ID ... /// /// /// /// /// public virtual async Task Get( TKey id, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await provider.GetAsync( id: id, includeBuilder: null, ignoreSoftDeleteds: true, cancellationToken: cancellationToken ); // return result; } /// /// Get All Exists Items ... /// /// /// /// /// public virtual async Task> GetAll( Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await provider.GetAllAsync( ignoreSoftDeleteds: true, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken ); // return result; } /// /// find an item by providing a Conditional Expression ... /// /// /// /// /// public virtual async Task FindOne( Expression> predicate, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await provider.FindOneAsync( predicate: predicate, ignoreSoftDeleteds: true, includeBuilder: includeBuilder, cancellationToken: cancellationToken ); // return result; } /// /// find a collection of Items by proving a Conditional Expression ... /// /// /// /// /// /// public virtual async Task> FindMany( Expression> predicate, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await provider.FindManyAsync( predicate: predicate, ignoreSoftDeleteds: true, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken ); // return result; } /// /// retrieve Items based on XQuery Pagination structure ... /// /// /// /// /// /// /// public virtual async Task> Query( XQuery query, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // var result = await provider.QueryAsync( query: query, predicate: predicate, ignoreSoftDeleteds: true, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken ); // return result; } /// /// retrieve Owned Items based on XQuery Pagination structure ... /// if supported ... /// /// /// /// /// /// /// /// public virtual async Task> QueryOwned( XQuery query, XUserClaimsInfoDto userInfo = null, Expression> predicate = null, Func, IOrderedQueryable> orderBuilder = null, Func, IIncludableQueryable> includeBuilder = null, CancellationToken cancellationToken = default ) { // Expression> predicateor = null; if (!predicate.IsNull()) { // var predicateFnc = predicate.Compile(); predicateor = x => predicateFnc(x) && IsOwned(x, userInfo); } else { predicateor = x => IsOwned(x, userInfo); } // var result = await provider.QueryAsync( query: query, predicate: predicateor, ignoreSoftDeleteds: true, orderBuilder: orderBuilder, includeBuilder: includeBuilder, cancellationToken: cancellationToken ); // return result; } /// /// Add an item values ... /// /// /// /// /// /// public virtual async Task Add( TDto item, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ) { // var result = await provider.AddAsync( item: item, saveChanges: true, connectionId: connectionId, cancellationToken: cancellationToken ); // return result; } /// /// Update an item values ... /// /// /// /// /// /// /// public virtual async Task Update( TKey id, TDto item, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ) { // // Check Permission ... var hasPermission = IsOwned(item, userInfo) || HasPermision(userInfo); if (!hasPermission) { XException.NotAllowed.Throw(); } // var result = await provider.UpdateAsync( id: id, item: item, saveChanges: true, connectionId: connectionId, cancellationToken: cancellationToken ); // return result; } /// /// remove an Item ... /// /// /// /// /// /// public virtual async Task Remove( TKey id, XUserClaimsInfoDto userInfo = null, string connectionId = null, CancellationToken cancellationToken = default ) { // // Check Permission ... var item = await Get( id: id, cancellationToken: cancellationToken ); var hasPermission = IsOwned(item, userInfo) || HasPermision(userInfo); if (!hasPermission) { XException.NotAllowed.Throw(); } // var result = await provider.RemoveAsync( id: id, saveChanges: true, softDelete: false, connectionId: connectionId, cancellationToken: cancellationToken ); // return result; } /// /// count all exists Items ... /// /// /// public virtual async Task Count( CancellationToken cancellationToken = default ) { // var result = await provider.CountAsync( ignoreSoftDeleteds: true, cancellationToken: cancellationToken ); // return result; } /// /// Check an Item exists or not ... /// /// /// /// public virtual async Task IsExists( TKey id, CancellationToken cancellationToken = default ) { // var result = await provider.IsExistsAsync( id: id, cancellationToken: cancellationToken ); // return result; } #endregion } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XHubContextFactory.cs using System; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using xPushService.Interfaces; namespace xPushService.Providers { public class XHubContextFactory : IXHubContextFactory { private readonly IServiceProvider services; public XHubContextFactory(IServiceProvider services) { this.services = services; } public IHubContext Create() where THub : Hub { return services.GetRequiredService>(); } } } ### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xPushService\Providers\XPushServiceUserNameProvider.cs using Microsoft.AspNetCore.SignalR; namespace xPushService.Providers { public class XPushServiceUserNameProvider : IUserIdProvider { public string GetUserId (HubConnectionContext connection) { // var result = connection.User?.Identity?.Name; return result; } } }