diff --git a/Controllers/XIBaseEntityController.cs b/Controllers/XIBaseEntityController.cs index 5ee8551..ac56a04 100644 --- a/Controllers/XIBaseEntityController.cs +++ b/Controllers/XIBaseEntityController.cs @@ -1,486 +1,714 @@ 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.Attributes; using xCommons.Configurations; using xCommons.Extensions; using xCommons.Providers; +using xDataService.Controllers; using xDataService.Interfaces; using xExceptions.Constants; using xIdentityService.Interfaces; using xModels.Base; using xModels.Dtos; -using xModels.Interfaces; -namespace xIdentityService.Controllers { +namespace xIdentityService.Controllers +{ [Authorize] - [RequireXPowered (false)] + [RequireXPowered(false)] public abstract class XIBaseEntityController : XIBaseController, IXEntityControllerActions - where TEntity : XBaseEntity { - public readonly IXBaseRepository repository; + where TEntity : XBaseEntity + { + // + #region Properties ... + public IXBaseRepository Repository { get; } - protected XIBaseEntityController ( - ILogger logger, - XAppConfiguration appConfiguration, - IXIdentityProvider identityProvider, - XValidationProvider validationProvider, - IXBaseRepository repository - ) : base ( - logger, - appConfiguration, - identityProvider, - validationProvider - ) { - // - this.repository = repository; - } + public Func, IOrderedQueryable> DefaultOrderBuilder { get; } + public Func, IIncludableQueryable> DefaultIncludeBuilder { get; } + #endregion + + // + #region Constructor ... + protected XIBaseEntityController( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXBaseRepository repository, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider + ) + { // - #region Interface Implementations ... - // - #region Retrieve ... - [HttpGet ("{id}")] - public virtual async Task> Get ( - [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotNull (id); - - // - // Get Result ... - var result = await repository - .GetAsync ( - id, - ignoreSoftDeleteds : ignoreSoftDeleteds, - containsDetail : containsDetail - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpGet] - public virtual async Task>> GetAll ( - [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false - ) { - // - try { - // - // Get Result ... - var result = await repository - .GetAllAsync ( - ignoreSoftDeleteds: ignoreSoftDeleteds, - containsDetail: containsDetail - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpGet ("FindOne/{query}")] - public virtual async Task> FindOne ( - [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotEmpty (query); - - // - // Get Result ... - var result = await repository - .FindOneAsync (t => - t.PropValuesContains (query), - ignoreSoftDeleteds : ignoreSoftDeleteds, - containsDetail : containsDetail - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpGet ("FindMany/{query}")] - public virtual async Task>> FindMany ( - [FromRoute] string query, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotEmpty (query); - - // - // Get Result ... - var result = await repository - .FindManyAsync (t => - t.PropValuesContains (query), - ignoreSoftDeleteds : ignoreSoftDeleteds, - containsDetail : containsDetail - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpGet ("Query")] - public virtual async Task>> Query ( - [FromQuery] XQuery query, [FromQuery] bool ignoreSoftDeleteds = true - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotNull (query); - - // - // Get Result ... - var result = await repository - .QueryAsync ( - query, - ignoreSoftDeleteds : ignoreSoftDeleteds - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - // - // TODO: Fix this ... - // [HttpGet ("RequestPage")] - // public virtual async Task>> RequestPage ( - // [FromQuery] XPageRequest request, [FromQuery] bool ignoreSoftDeleteds = true, [FromQuery] bool containsDetail = false - // ) { - // // - // try { - // // - // // Validate Args ... - // ValidationProvider.NotNull (request); - - // // - // // Get Result ... - // var result = await repository - // .RequestPageAsync ( - // request, - // ignoreSoftDeleteds : ignoreSoftDeleteds, - // containsDetail : containsDetail - // ); - - // // - // return Ok (result - // .ToDynamicObject ()); - // } catch (Exception ex) { - // // - // var result = GetExceptionActionResult (ex); - // return result; - // } - // } - #endregion - - // - #region Add ... - [HttpPost] - public virtual async Task> Add ( - [FromBody] TEntity item - ) { - // - try { - // - // Validate Args ... - if (!ModelState.IsValid) { - XException.InvalidArgs.Throw (); - } - ValidationProvider.NotNull (item); - - // - // Get Result ... - var result = await repository - .AddAsync ( - item, - saveChanges : true - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpPost ("AddOrUpdate")] - public virtual async Task> AddOrUpdate ( - [FromBody] TEntity item - ) { - // - try { - // - // Validate Args ... - if (!ModelState.IsValid) { - XException.InvalidArgs.Throw (); - } - ValidationProvider.NotNull (item); - - // - // Get Result ... - var result = await repository - .AddOrUpdateAsync ( - item, - saveChanges : true - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpPost ("AddMany")] - public virtual async Task AddMany ( - [FromBody] XBaseRangeRequest request - ) { - // - try { - // - // Validate Args ... - if (!ModelState.IsValid) { - XException.InvalidArgs.Throw (); - } - await ValidationProvider - .GroupValidationBuilder () - .AddNotNull (request) - .AddNotZeroChilds (request.Items) - .ValidateGroupAsync (); - - // - // Get Result ... - await repository - .AddRangeAsync ( - request.Items, - saveChanges : true - ); - - // - return Ok (); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - #endregion - - // - #region Update ... - [HttpPut ("{id}")] - public virtual async Task> Update ( - [FromRoute] TKey id, [FromBody] TEntity item - ) { - // - try { - // - // Validate Args ... - if (!ModelState.IsValid) { - XException.InvalidArgs.Throw (); - } - await ValidationProvider - .GroupValidationBuilder () - .AddNotNull (id, item) - .ValidateGroupAsync (); - - // - // Get Result ... - var result = await repository - .UpdateAsync ( - id, - item, - saveChanges : true - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpPost ("UpdateMany")] - public virtual async Task> UpdateMany ( - [FromBody] XBaseRangeRequest request - ) { - // - try { - // - // Validate Args ... - if (!ModelState.IsValid) { - XException.InvalidArgs.Throw (); - } - await ValidationProvider - .GroupValidationBuilder () - .AddNotNull (request) - .AddNotZeroChilds (request.Items) - .ValidateGroupAsync (); - - // - // Get Result ... - var result = await repository - .UpdateRangeAsync ( - request.Items, - saveChanges : true - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - #endregion - - // - #region Exists ... - [HttpGet ("{id}/IsExists")] - public virtual async Task> IsExists ( - [FromRoute] TKey id, [FromQuery] bool ignoreSoftDeleteds = true - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotNull (id); - - // - // Get Result ... - var result = await repository - .IsExistsAsync ( - id, - ignoreSoftDeleteds : ignoreSoftDeleteds - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - #endregion - - // - #region Remove ... - [HttpDelete ("{id}")] - public virtual async Task> Remove ( - [FromRoute] TKey id, - bool softDelete = true - ) { - // - try { - // - // Validate Args ... - ValidationProvider.NotNull (id); - - // - // Get Result ... - var result = await repository - .RemoveAsync ( - id, - saveChanges : true, - softDelete : softDelete - ); - - // - return Ok (result - .ToDynamicObject ()); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - - [HttpPost ("RemoveMany")] - public virtual async Task RemoveMany ( - [FromBody] XBaseRangeRequest request, - bool softDelete = true - ) { - // - try { - // - // Validate Args ... - await ValidationProvider - .GroupValidationBuilder () - .AddNotNull (request) - .AddNotZeroChilds (request.Items) - .ValidateGroupAsync (); - - // - // Get Result ... - await repository - .RemoveRangeAsync ( - request.Items, - saveChanges : true, - softDelete : softDelete - ); - - // - return Ok (); - } catch (Exception ex) { - // - var result = GetExceptionActionResult (ex); - return result; - } - } - #endregion - #endregion + Repository = repository; + DefaultOrderBuilder = defaultOrderBuilder; + DefaultIncludeBuilder = defaultIncludeBuilder; } + #endregion + + // + #region Actions ... + // + #region Add ... + /// + /// Add Specified Item ... + /// + /// + /// + /// + /// + /// + [HttpPost] + public virtual async Task> Add( + [FromBody] TEntity item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + ValidationProvider.NotNull(item); + + // + // Get Result ... + var result = await Repository + .AddAsync( + item, + saveChanges: true, + cancellationToken: cancellationToken + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Add or Update Specified Item ... + /// + /// + /// + /// + /// + /// + [HttpPost("AddOrUpdate")] + public virtual async Task> AddOrUpdate( + [FromBody] TEntity item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + ValidationProvider.NotNull(item); + + // + // Get Result ... + var result = await Repository + .AddOrUpdateAsync( + item, + saveChanges: true, + cancellationToken: cancellationToken + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Add a Collection of Items ... + /// + /// + /// + /// + /// + /// + [HttpPost("AddMany")] + public virtual async Task AddMany( + [FromBody] XBaseRangeRequest request, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(request) + .AddNotZeroChilds(request.Items) + .ValidateGroupAsync(); + + // + // Get Result ... + await Repository + .AddRangeAsync( + request.Items, + saveChanges: true, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + + // + #region Retrieve ... + /// + /// Get Specified Item ... + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet("{id}")] + public virtual async Task> Get( + [FromRoute] TKey id, + [FromQuery] bool ignoreSoftDeleteds = true, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + ValidationProvider.NotNull(id); + + // + // Get Result ... + var result = await Repository + .GetAsync( + id, + includeBuilder: useDefaultIncludes + ? DefaultIncludeBuilder + : null, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Get All Items ... + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet] + public virtual async Task>> GetAll( + [FromQuery] bool ignoreSoftDeleteds = true, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Get Result ... + var result = await Repository + .GetAllAsync( + orderBuilder: useDefaultOrders + ? DefaultOrderBuilder + : null, + includeBuilder: useDefaultIncludes + ? DefaultIncludeBuilder + : null, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Find Specified Item ... + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet("FindOne/{query}")] + public virtual async Task> FindOne( + [FromRoute] string query, + [FromQuery] bool ignoreSoftDeleteds = true, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + ValidationProvider.NotEmpty(query); + + // + // Get Result ... + var result = await Repository + .FindOneAsync( + predicate: t => + t.PropValuesContains(query), + includeBuilder: useDefaultIncludes + ? DefaultIncludeBuilder + : null, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Find Many Items ... + /// + /// + /// + /// + /// + /// + /// + /// + /// + [HttpGet("FindMany/{query}")] + public virtual async Task>> FindMany( + [FromRoute] string query, + [FromQuery] bool ignoreSoftDeleteds = true, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + ValidationProvider.NotEmpty(query); + + // + // Get Result ... + var result = await Repository + .FindManyAsync( + predicate: t => + t.PropValuesContains(query), + orderBuilder: useDefaultOrders + ? DefaultOrderBuilder + : null, + includeBuilder: useDefaultIncludes + ? DefaultIncludeBuilder + : null, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Retrieve Items Based on Query Mechanism ... + /// + /// + /// + /// + /// + /// + /// + /// + /// + [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 Args ... + ValidationProvider.NotNull(query); + + // + // Get Result ... + var result = await Repository + .QueryAsync( + query: query, + orderBuilder: useDefaultOrders + ? DefaultOrderBuilder + : null, + includeBuilder: useDefaultIncludes + ? DefaultIncludeBuilder + : null, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + + // + #region Update ... + /// + /// Update Item ... + /// + /// + /// + /// + /// + /// + /// + [HttpPut("{id}")] + public virtual async Task> Update( + [FromRoute] TKey id, + [FromBody] TEntity item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(id, item) + .ValidateGroupAsync(); + + // + // Get Result ... + var result = await Repository + .UpdateAsync( + id: id, + item: item, + saveChanges: true, + cancellationToken: cancellationToken + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Update a Collection of items ... + /// + /// + /// + /// + /// + /// + [HttpPost("UpdateMany")] + public virtual async Task> UpdateMany( + [FromBody] XBaseRangeRequest request, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(request) + .AddNotZeroChilds(request.Items) + .ValidateGroupAsync(); + + // + // Get Result ... + var result = await Repository + .UpdateRangeAsync( + saveChanges: true, + items: request.Items, + cancellationToken: cancellationToken + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + + // + #region Exists ... + /// + ///Check an Item Exists or not ... + /// + /// + /// + /// + /// + /// + /// + [HttpGet("{id}/IsExists")] + public virtual async Task> IsExists( + [FromRoute] TKey id, + [FromQuery] bool ignoreSoftDeleteds = true, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + ValidationProvider.NotNull(id); + + // + // Get Result ... + var result = await Repository + .IsExistsAsync( + id: id, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + + // + #region Remove ... + /// + /// Remove an Items ... + /// + /// + /// + /// + /// + /// + /// + [HttpDelete("{id}")] + public virtual async Task> Remove( + [FromRoute] TKey id, + [FromQuery] bool softDelete = true, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + ValidationProvider.NotNull(id); + + // + // Get Result ... + var result = await Repository + .RemoveAsync( + id: id, + saveChanges: true, + softDelete: softDelete, + cancellationToken: cancellationToken + ); + + // + return Ok(result + .ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + + /// + /// Remove Many Items ... + /// + /// + /// + /// + /// + /// + /// + [HttpPost("RemoveMany")] + public virtual async Task RemoveMany( + [FromBody] XBaseRangeRequest request, + [FromQuery] bool softDelete = true, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate Args ... + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(request) + .AddNotZeroChilds(request.Items) + .ValidateGroupAsync(); + + // + // Get Result ... + await Repository + .RemoveRangeAsync( + saveChanges: true, + items: request.Items, + softDelete: softDelete, + cancellationToken: cancellationToken + ); + + // + return Ok(); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + #endregion + #endregion + } } \ No newline at end of file diff --git a/xIdentityService.csproj b/xIdentityService.csproj index 6242193..064dd1f 100644 --- a/xIdentityService.csproj +++ b/xIdentityService.csproj @@ -28,12 +28,10 @@ - - + - +