Compare commits

...
10 Commits
Author SHA1 Message Date
saherelm ba3adfeadb cleanup Dependencies ... 2026-07-30 15:58:33 +03:30
saherelm 92ecffc935 last ... 2026-07-29 00:15:28 +03:30
saherelm 64c7eb9824 last ... 2026-07-28 14:27:09 +03:30
saherelm dd5096d885 last ... 2026-07-26 21:19:04 +03:30
saherelm 98c6064d6f last ... 2026-06-12 23:44:23 +03:30
saherelm 34a0e9c97e fix some Parmas Routing ... 2026-06-12 17:24:25 +03:30
saherelm b4ffd14009 Update Lang Version to 12 ...
Add Support for Get all As Async Enumerable ...
2026-06-12 02:12:25 +03:30
saherelm cd36b73ad1 last ... 2026-05-28 07:33:20 +03:30
saherelm c4bef7e512 last ... 2026-05-28 02:31:01 +03:30
saherelm 29821a9326 last ... 2026-05-27 16:09:54 +03:30
14 changed files with 1362 additions and 20 deletions
+39
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
@@ -271,6 +272,44 @@ namespace xPushService.Base
return result; return result;
} }
/// <summary>
/// retrieve all exists Dtos
/// as Async Enumerable ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> 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;
}
}
/// <summary> /// <summary>
/// find an Item by providing a Conditional Expression ... /// find an Item by providing a Conditional Expression ...
/// </summary> /// </summary>
+1 -1
View File
@@ -17,7 +17,7 @@ using xPushService.Interfaces;
namespace xPushService.Base namespace xPushService.Base
{ {
public abstract class XBaseEntityProvider<TEntity, TKey, THub> : IXBaseEntityProviderr<TEntity, TKey, THub> public abstract class XBaseEntityProvider<TEntity, TKey, THub> : IXBaseEntityProvider<TEntity, TKey, THub>
where TEntity : XBaseEntity<TKey> where TEntity : XBaseEntity<TKey>
where THub : XBaseEntityHub<TEntity, TKey> where THub : XBaseEntityHub<TEntity, TKey>
{ {
+514
View File
@@ -0,0 +1,514 @@
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<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseProvidedController<TEntity, TDto, TKey, THub>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
where THub : XBaseDtoHub<TEntity, TDto, TKey>
{
private readonly IXBaseProvided<TEntity, TDto, TKey, THub> provider;
private readonly Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder;
private readonly Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder;
protected XBaseProvidedController(
ILogger<XBaseProvidedController<TEntity, TDto, TKey, THub>> logger,
XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider,
XValidationProvider validationProvider,
IXBaseProvided<TEntity, TDto, TKey, THub> provider,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
) : base(
logger,
appConfiguration,
identityProvider,
validationProvider
)
{
this.provider = provider;
this.defaultOrderBuilder = defaultOrderBuilder;
this.defaultIncludeBuilder = defaultIncludeBuilder;
}
//
#region Retrieve ...
/// <summary>
/// Get Specified Item by ID ...
/// </summary>
/// <param name="id"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}")]
public virtual async Task<ActionResult<TDto>> 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;
}
}
/// <summary>
/// Get All Exists Items ...
/// </summary>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("")]
public virtual async Task<ActionResult<IEnumerable<TDto>>> 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;
}
}
/// <summary>
/// Find an item by providing a Conditional Expression ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Find/One")]
public virtual async Task<ActionResult<TDto>> 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;
}
}
/// <summary>
/// Find a collection of Items by proving a Query Search ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Find/Many")]
public virtual async Task<ActionResult<IEnumerable<TDto>>> 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;
}
}
/// <summary>
/// Retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Query")]
public virtual async Task<ActionResult<XQueryResult<TDto>>> 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;
}
}
/// <summary>
/// Retrieve Owned Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Query/Owned")]
public virtual async Task<ActionResult<XQueryResult<TDto>>> 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 ...
/// <summary>
/// Add an item ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("")]
public virtual async Task<ActionResult<TDto>> 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;
}
}
/// <summary>
/// Update an item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPut("{id}")]
public virtual async Task<ActionResult<TDto>> 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;
}
}
/// <summary>
/// Remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public virtual async Task<ActionResult<TDto>> 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
}
}
@@ -4,6 +4,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -21,13 +22,14 @@ using xPushService.Interfaces;
namespace xPushService.Controllers namespace xPushService.Controllers
{ {
[AllowAnonymous]
public abstract class XBaseRepositoryProviderController<TEntity, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseRepositoryProviderController<TEntity, TKey, THub> public abstract class XBaseRepositoryProviderController<TEntity, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseRepositoryProviderController<TEntity, TKey, THub>
where TEntity : XBaseEntity<TKey> where TEntity : XBaseEntity<TKey>
where THub : XBaseEntityHub<TEntity, TKey> where THub : XBaseEntityHub<TEntity, TKey>
{ {
// //
#region Properties ... #region Properties ...
public IXBaseEntityProviderr<TEntity, TKey, THub> Provider { get; } public IXBaseEntityProvider<TEntity, TKey, THub> Provider { get; }
public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; } public Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; } public Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
#endregion #endregion
@@ -37,9 +39,9 @@ namespace xPushService.Controllers
XAppConfiguration appConfiguration, XAppConfiguration appConfiguration,
IXIdentityProvider identityProvider, IXIdentityProvider identityProvider,
XValidationProvider validationProvider, XValidationProvider validationProvider,
IXBaseEntityProviderr<TEntity, TKey, THub> provider, IXBaseEntityProvider<TEntity, TKey, THub> provider,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
) : base( ) : base(
logger: logger, logger: logger,
appConfiguration: appConfiguration, appConfiguration: appConfiguration,
@@ -427,7 +429,7 @@ namespace xPushService.Controllers
} }
/// <summary> /// <summary>
/// find a collection of Items by proving a Conditional Expression ... /// find a collection of Items by proving a Query Search ...
/// </summary> /// </summary>
/// <param name="query"></param> /// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param> /// <param name="ignoreSoftDeleteds"></param>
@@ -480,7 +482,7 @@ namespace xPushService.Controllers
} }
/// <summary> /// <summary>
/// retrieve Items based on XQuery Pagination structure ... /// Retrieve Items based on XQuery Pagination structure ...
/// </summary> /// </summary>
/// <param name="query"></param> /// <param name="query"></param>
/// <param name="ignoreSoftDeleteds"></param> /// <param name="ignoreSoftDeleteds"></param>
@@ -4,6 +4,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -21,6 +22,7 @@ using xPushService.Interfaces;
namespace xPushService.Controllers namespace xPushService.Controllers
{ {
[AllowAnonymous]
public abstract class XBaseServiceProviderController<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseServiceProviderController<TEntity, TDto, TKey, THub> public abstract class XBaseServiceProviderController<TEntity, TDto, TKey, THub> : XBaseIdentityApiV1Controller, IXBaseServiceProviderController<TEntity, TDto, TKey, THub>
where TEntity : XBaseEntity<TKey> where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey> where TDto : XBaseEntityDto<TKey>
@@ -41,8 +43,8 @@ namespace xPushService.Controllers
IXIdentityProvider identityProvider, IXIdentityProvider identityProvider,
XValidationProvider validationProvider, XValidationProvider validationProvider,
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider, IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> defaultOrderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> defaultIncludeBuilder = null
) : base( ) : base(
logger, logger,
appConfiguration, appConfiguration,
+2 -1
View File
@@ -14,7 +14,6 @@ using xExceptions.Constants;
using xPushService.Configurations; using xPushService.Configurations;
using xPushService.Constants; using xPushService.Constants;
using xPushService.Helpers; using xPushService.Helpers;
using xPushService.Interfaces;
using xPushService.Providers; using xPushService.Providers;
namespace xPushService.DI namespace xPushService.DI
@@ -62,6 +61,7 @@ namespace xPushService.DI
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="services"></param>
/// <param name="config"></param> /// <param name="config"></param>
/// <param name="lifeTime"></param>
public static void AddXPushService( public static void AddXPushService(
this IServiceCollection services, this IServiceCollection services,
IConfiguration config, IConfiguration config,
@@ -81,6 +81,7 @@ namespace xPushService.DI
/// </summary> /// </summary>
/// <param name="services"></param> /// <param name="services"></param>
/// <param name="config"></param> /// <param name="config"></param>
/// <param name="lifeTime"></param>
public static void AddXPushService( public static void AddXPushService(
this IServiceCollection services, this IServiceCollection services,
XPushServiceConfiguration config, XPushServiceConfiguration config,
+1 -2
View File
@@ -10,14 +10,13 @@ namespace xPushService.Helpers {
/// <summary> /// <summary>
/// a collection of Hubs for Registring ... /// a collection of Hubs for Registring ...
/// </summary> /// </summary>
/// <typeparam name="XHubDescriptor"></typeparam>
/// <returns></returns> /// <returns></returns>
private List<XHubDescriptor> hubs = new List<XHubDescriptor> (); private List<XHubDescriptor> hubs = new List<XHubDescriptor> ();
/// <summary> /// <summary>
/// add specified hub to provided hubs for registration ... /// add specified hub to provided hubs for registration ...
/// </summary> /// </summary>
/// <param name="reoute"></param> /// <param name="route"></param>
/// <typeparam name="TXHub"></typeparam> /// <typeparam name="TXHub"></typeparam>
public void AddHub<TXHub> (string route) where TXHub : XBaseHub { public void AddHub<TXHub> (string route) where TXHub : XBaseHub {
// //
+16
View File
@@ -133,6 +133,22 @@ namespace xPushService.Interfaces
CancellationToken cancellationToken = default CancellationToken cancellationToken = default
); );
/// <summary>
/// retrieve all exists Dtos
/// as Async Enumerable ...
/// </summary>
/// <param name="ignoreSoftDeleteds"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
IAsyncEnumerable<TDto> GetAllAsAsyncEnumerable(
bool ignoreSoftDeleteds = true,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary> /// <summary>
/// find an Item by providing a Conditional Expression ... /// find an Item by providing a Conditional Expression ...
/// </summary> /// </summary>
+1 -1
View File
@@ -21,7 +21,7 @@ namespace xPushService.Interfaces
/// </summary> /// </summary>
/// <typeparam name="TEntity"></typeparam> /// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam> /// <typeparam name="TKey"></typeparam>
public interface IXBaseEntityProviderr<TEntity, TKey, THub> public interface IXBaseEntityProvider<TEntity, TKey, THub>
where TEntity : XBaseEntity<TKey> where TEntity : XBaseEntity<TKey>
where THub : XBaseEntityHub<TEntity, TKey> where THub : XBaseEntityHub<TEntity, TKey>
{ {
+185
View File
@@ -0,0 +1,185 @@
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
{
/// <summary>
/// a Provided Service Used for Providing Data Based on Validations of Users ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="THub"></typeparam>
public interface IXBaseProvided<TEntity, TDto, TKey, THub>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
where THub : XBaseDtoHub<TEntity, TDto, TKey>
{
/// <summary>
/// Get Specified Item by ID ...
/// </summary>
/// <param name="id"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TDto> Get(
TKey id,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get All Exists Items ...
/// </summary>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<TDto>> GetAll(
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Find an item by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TDto> FindOne(
Expression<Func<TEntity, bool>> predicate,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Find a collection of Items by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<TDto>> FindMany(
Expression<Func<TEntity, bool>> predicate,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XQueryResult<TDto>> Query(
XQuery query,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Owned Items based on XQuery Pagination structure ...
/// if supported ...
/// </summary>
/// <param name="query"></param>
/// <param name="userInfo"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<XQueryResult<TDto>> QueryOwned(
XQuery query,
XUserClaimsInfoDto userInfo = null,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Add an item values ...
/// </summary>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TDto> Add(
TDto item,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// Update an item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TDto> Update(
TKey id,
TDto item,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<TDto> Remove(
TKey id,
XUserClaimsInfoDto userInfo = null,
string connectionId = null,
CancellationToken cancellationToken = default
);
/// <summary>
/// count all exists Items ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<int> Count(
CancellationToken cancellationToken = default
);
/// <summary>
/// Check an Item exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<bool> IsExists(
TKey id,
CancellationToken cancellationToken = default
);
}
}
+157
View File
@@ -0,0 +1,157 @@
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
{
/// <summary>
/// a Provided Controller Used for Providing a Provided Service Actions ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="THub"></typeparam>
public interface IXBaseProvidedController<TEntity, TDto, TKey, THub>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
where THub : XBaseDtoHub<TEntity, TDto, TKey>
{
//
#region Retrieve ...
/// <summary>
/// Get Specified Item by ID ...
/// </summary>
/// <param name="id"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("{id}")]
Task<ActionResult<TDto>> Get(
[FromRoute] TKey id,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Get All Exists Items ...
/// </summary>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("")]
Task<ActionResult<IEnumerable<TDto>>> GetAll(
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Find an item by providing a Conditional Expression ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Find/One")]
Task<ActionResult<TDto>> FindOne(
[FromQuery] string query,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Find a collection of Items by proving a Query Search ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Find/Many")]
Task<ActionResult<IEnumerable<TDto>>> FindMany(
[FromQuery] string query,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Query")]
Task<ActionResult<XQueryResult<TDto>>> Query(
[FromQuery] XQuery query,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
/// <summary>
/// Retrieve Owned Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="useDefaultOrders"></param>
/// <param name="useDefaultIncludes"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("Query/Owned")]
Task<ActionResult<XQueryResult<TDto>>> QueryOwned(
[FromQuery] XQuery query,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
);
#endregion
//
#region Add/Update/Remove ...
/// <summary>
/// Add an item ...
/// </summary>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("")]
Task<ActionResult<TDto>> Add(
[FromBody] TDto item,
CancellationToken cancellationToken = default
);
/// <summary>
/// Update an item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPut("{id}")]
Task<ActionResult<TDto>> Update(
[FromRoute] TKey id,
[FromBody] TDto item,
CancellationToken cancellationToken = default
);
/// <summary>
/// Remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpDelete("{id}")]
Task<ActionResult<TDto>> Remove(
[FromRoute] TKey id,
CancellationToken cancellationToken = default
);
#endregion
}
}
@@ -17,7 +17,7 @@ namespace xPushService.Interfaces
{ {
// //
#region Properties ... #region Properties ...
IXBaseEntityProviderr<TEntity, TKey, THub> Provider { get; } IXBaseEntityProvider<TEntity, TKey, THub> Provider { get; }
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; } Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> DefaultOrderBuilder { get; }
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; } Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> DefaultIncludeBuilder { get; }
#endregion #endregion
+418
View File
@@ -0,0 +1,418 @@
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
{
/// <summary>
/// a Provided Service Used for Providing Data Based on Validations of Users ...
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TDto"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="THub"></typeparam>
public abstract class XBaseProvided<TEntity, TDto, TKey, THub> : IXBaseProvided<TEntity, TDto, TKey, THub>
where TEntity : XBaseEntity<TKey>
where TDto : XBaseEntityDto<TKey>
where THub : XBaseDtoHub<TEntity, TDto, TKey>
{
//
#region Props ...
private readonly string[] permittedRoles;
private readonly IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider;
#endregion
//
#region Constructor ...
protected XBaseProvided(
IXBaseDtoProvider<TEntity, TDto, TKey, THub> provider,
string[] permittedRoles = null
)
{
this.provider = provider;
this.permittedRoles = permittedRoles;
}
#endregion
/// <summary>
/// Check an Items is Owned for User or not ...
/// </summary>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <returns></returns>
public abstract bool IsOwned(
TDto item,
XUserClaimsInfoDto userInfo
);
public abstract bool IsOwned(
TEntity item,
XUserClaimsInfoDto userInfo
);
/// <summary>
/// Check User Has Permission for Manipulate Data or not ...
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
public bool HasPermision(
XUserClaimsInfoDto userInfo
)
{
//
var result =
!permittedRoles.HasChild() ||
(!userInfo.IsNullOrDefault() &&
userInfo.HasAccess(permittedRoles));
//
return result;
}
//
#region Provided Actions ...
/// <summary>
/// Get Specified Item by ID ...
/// </summary>
/// <param name="id"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> Get(
TKey id,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.GetAsync(
id: id,
includeBuilder: null,
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Get All Exists Items ...
/// </summary>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TDto>> GetAll(
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.GetAllAsync(
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// find an item by providing a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> FindOne(
Expression<Func<TEntity, bool>> predicate,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.FindOneAsync(
predicate: predicate,
ignoreSoftDeleteds: true,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// find a collection of Items by proving a Conditional Expression ...
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<IEnumerable<TDto>> FindMany(
Expression<Func<TEntity, bool>> predicate,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.FindManyAsync(
predicate: predicate,
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// retrieve Items based on XQuery Pagination structure ...
/// </summary>
/// <param name="query"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<XQueryResult<TDto>> Query(
XQuery query,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.QueryAsync(
query: query,
predicate: predicate,
ignoreSoftDeleteds: true,
orderBuilder: orderBuilder,
includeBuilder: includeBuilder,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// retrieve Owned Items based on XQuery Pagination structure ...
/// if supported ...
/// </summary>
/// <param name="query"></param>
/// <param name="userInfo"></param>
/// <param name="predicate"></param>
/// <param name="orderBuilder"></param>
/// <param name="includeBuilder"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<XQueryResult<TDto>> QueryOwned(
XQuery query,
XUserClaimsInfoDto userInfo = null,
Expression<Func<TEntity, bool>> predicate = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBuilder = null,
Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> includeBuilder = null,
CancellationToken cancellationToken = default
)
{
//
Expression<Func<TEntity, bool>> 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;
}
/// <summary>
/// Add an item values ...
/// </summary>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> 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;
}
/// <summary>
/// Update an item values ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> 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;
}
/// <summary>
/// remove an Item ...
/// </summary>
/// <param name="id"></param>
/// <param name="userInfo"></param>
/// <param name="connectionId"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<TDto> 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;
}
/// <summary>
/// count all exists Items ...
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<int> Count(
CancellationToken cancellationToken = default
)
{
//
var result = await provider.CountAsync(
ignoreSoftDeleteds: true,
cancellationToken: cancellationToken
);
//
return result;
}
/// <summary>
/// Check an Item exists or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public virtual async Task<bool> IsExists(
TKey id,
CancellationToken cancellationToken = default
)
{
//
var result = await provider.IsExistsAsync(
id: id,
cancellationToken: cancellationToken
);
//
return result;
}
#endregion
}
}
+15 -6
View File
@@ -1,12 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<!-- Runtime Definition --> <!-- Runtime Definition -->
<PropertyGroup> <PropertyGroup>
<Version>1.0.0</Version> <Version>1.0.0</Version>
<LangVersion>8.0</LangVersion> <LangVersion>12.0</LangVersion>
<Authors>Hadi Khazaee Asl</Authors> <Authors>Hadi Khazaee Asl</Authors>
<Company>SaherElm IT Center</Company> <Company>SaherElm IT Center</Company>
<PackageId>xDashboard.xPushService</PackageId> <PackageId>xDashboard.xPushService</PackageId>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<Description> <Description>
it is a Part of xDashboard Projects on SaherElm IT Center which provides all required models it is a Part of xDashboard Projects on SaherElm IT Center which provides all required models
and actions in related to and actions in related to
@@ -19,7 +21,8 @@
<!-- Icon Handling --> <!-- Icon Handling -->
<ItemGroup> <ItemGroup>
<None Include="../../Resources/Images/favicon.png" Link="icon.png" Pack="true" PackagePath="\icon.png" /> <None Include="../../Resources/Images/favicon.png" Link="icon.png" Pack="true"
PackagePath="\icon.png" />
</ItemGroup> </ItemGroup>
<!-- Local Modules --> <!-- Local Modules -->
@@ -28,9 +31,6 @@
<!-- Local Dependencies --> <!-- Local Dependencies -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\xModels\xModels.csproj" />
<ProjectReference Include="..\xCommons\xCommons.csproj" />
<ProjectReference Include="..\xDataService\xDataService.csproj" />
<ProjectReference Include="..\xIdentityService\xIdentityService.csproj" /> <ProjectReference Include="..\xIdentityService\xIdentityService.csproj" />
</ItemGroup> </ItemGroup>
@@ -40,6 +40,15 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.31" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.31" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.31" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.31" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.17" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson"
Version="5.0.17" />
</ItemGroup> </ItemGroup>
<!-- For XML Documentation Support -->
<PropertyGroup>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
</Project> </Project>