From 831c7004a8aa01547f7389359b705eb79915bfe4 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 8 Aug 2026 18:07:28 +0330 Subject: [PATCH] last works on Models ... --- .../Dtos/IXAiProjectRepositoryService.cs | 215 ++++- Interfaces/Enrichers/IXAiProjectEnricher.cs | 20 +- .../IXAiConversationTitleResourceProvider.cs | 2 +- .../IXAiProjectDescriptionResourceProvider.cs | 2 +- .../IXAiProjectTitleResourceProvider.cs | 2 +- .../Dtos/XAiConversationRepositoryService.cs | 10 +- Providers/Dtos/XAiMessageRepositoryService.cs | 474 ++++++++++- Providers/Dtos/XAiProjectRepositoryService.cs | 790 +++++++++++++++++- .../Enrichers/XAiConversationEnricher.cs | 1 + Providers/Enrichers/XAiMessageEnricher.cs | 1 + Providers/Enrichers/XAiProjectEnricher.cs | 78 +- .../XAiConversationTitleResourceProvider.cs | 10 +- .../XAiProjectDescriptionResourceProvider.cs | 5 +- Providers/XAiProjectTitleResourceProvider.cs | 5 +- 14 files changed, 1584 insertions(+), 31 deletions(-) diff --git a/Interfaces/Dtos/IXAiProjectRepositoryService.cs b/Interfaces/Dtos/IXAiProjectRepositoryService.cs index 7699ce7..82dcc77 100644 --- a/Interfaces/Dtos/IXAiProjectRepositoryService.cs +++ b/Interfaces/Dtos/IXAiProjectRepositoryService.cs @@ -1,10 +1,223 @@ 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 xAiModels.Models.Dtos; using xAiModels.Models.Entities; using xDataService.Interfaces; +using xModels.Dtos; namespace xAiModels.Interfaces.Dtos { public interface IXAiProjectRepositoryService : IXBaseRepositoryService - { } + { + + // + #region Actions ... + // + #region Add ... + /// + /// add a new Dto ... + /// + /// + /// + /// + /// + /// + Task AddAsync( + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + /// + /// add or update a Dto (add if not exists/update if exists) ... + /// + /// + /// + /// + /// + /// + Task AddOrUpdateAsync( + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + #endregion + + // + #region Update ... + /// + /// Update an Dto values ... + /// + /// + /// + /// + /// + /// + /// + Task UpdateAsync( + Guid id, + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + #endregion + + // + #region Remove ... + /// + /// remove an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + /// + Task RemoveAsync( + Guid id, + bool softDelete = false, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + /// + /// remove an Dto ... + /// + /// + /// + /// + /// + /// + /// + Task RemoveAsync( + XAiProjectDto item, + bool softDelete = false, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + #endregion + + // + #region Retrieve ... + /// + /// retrieve an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + /// + Task GetAsync( + Guid id, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + /// + /// retrieve all exists Dtos ... + /// + /// + /// + /// + /// + /// + /// + Task> GetAllAsync( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + /// + /// retrieve all exists Dtos + /// as Async Enumerable ... + /// + /// + /// + /// + /// + /// + /// + IAsyncEnumerable GetAllAsAsyncEnumerable( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + /// + /// find an Dto by providing a Conditional Expression ... + /// + /// + /// + /// + /// + /// + /// + Task FindOneAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + 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, + bool fillConversations = true, + 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, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + #endregion + #endregion + } } \ No newline at end of file diff --git a/Interfaces/Enrichers/IXAiProjectEnricher.cs b/Interfaces/Enrichers/IXAiProjectEnricher.cs index 3ec7cbb..3e4a1ae 100644 --- a/Interfaces/Enrichers/IXAiProjectEnricher.cs +++ b/Interfaces/Enrichers/IXAiProjectEnricher.cs @@ -1,8 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; using xAiModels.Models.Dtos; using xDataService.Interfaces; namespace xAiModels.Interfaces.Enrichers { public interface IXAiProjectEnricher : IXBaseEnricher - { } + { + + Task EnrichAsync( + XAiProjectDto source, + XAiProjectDto destination, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + + Task EnrichRangeAsync( + IEnumerable sources, + IEnumerable destinations, + bool fillConversations = true, + CancellationToken cancellationToken = default + ); + } } \ No newline at end of file diff --git a/Interfaces/IXAiConversationTitleResourceProvider.cs b/Interfaces/IXAiConversationTitleResourceProvider.cs index 67e2cfe..1321025 100644 --- a/Interfaces/IXAiConversationTitleResourceProvider.cs +++ b/Interfaces/IXAiConversationTitleResourceProvider.cs @@ -2,6 +2,6 @@ using xStringService.Interfaces; namespace xAiModels.Interfaces { - public interface IXAiConversationTitleResourceProvider : IXItemResourceProvider + public interface IXAiConversationTitleResourceProvider : IXOwnedItemResourceProvider { } } \ No newline at end of file diff --git a/Interfaces/IXAiProjectDescriptionResourceProvider.cs b/Interfaces/IXAiProjectDescriptionResourceProvider.cs index 76feb6d..840129e 100644 --- a/Interfaces/IXAiProjectDescriptionResourceProvider.cs +++ b/Interfaces/IXAiProjectDescriptionResourceProvider.cs @@ -2,6 +2,6 @@ using xStringService.Interfaces; namespace xAiModels.Interfaces { - public interface IXAiProjectDescriptionResourceProvider : IXItemResourceProvider + public interface IXAiProjectDescriptionResourceProvider : IXOwnedItemResourceProvider { } } \ No newline at end of file diff --git a/Interfaces/IXAiProjectTitleResourceProvider.cs b/Interfaces/IXAiProjectTitleResourceProvider.cs index e5ab983..e909119 100644 --- a/Interfaces/IXAiProjectTitleResourceProvider.cs +++ b/Interfaces/IXAiProjectTitleResourceProvider.cs @@ -2,6 +2,6 @@ using xStringService.Interfaces; namespace xAiModels.Interfaces { - public interface IXAiProjectTitleResourceProvider : IXItemResourceProvider + public interface IXAiProjectTitleResourceProvider : IXOwnedItemResourceProvider { } } \ No newline at end of file diff --git a/Providers/Dtos/XAiConversationRepositoryService.cs b/Providers/Dtos/XAiConversationRepositoryService.cs index face815..7af7bdb 100644 --- a/Providers/Dtos/XAiConversationRepositoryService.cs +++ b/Providers/Dtos/XAiConversationRepositoryService.cs @@ -5,8 +5,8 @@ using System.Linq.Expressions; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -using AutoMapper; using Microsoft.EntityFrameworkCore.Query; +using xAiModels.Configurations; using xAiModels.Interfaces.Dtos; using xAiModels.Interfaces.Enrichers; using xAiModels.Interfaces.Entities; @@ -24,11 +24,13 @@ namespace xAiModels.Providers.Dtos public XAiConversationRepositoryService( IXAiConversationEnricher enricher, - IXAiConversationRepository repository, - IEnumerable mapperProfiles = null + IXAiConversationRepository repository ) : base( repository, - mapperProfiles + mapperProfiles: + [ + new XAiModelMappersProfile() + ] ) { this.enricher = enricher; diff --git a/Providers/Dtos/XAiMessageRepositoryService.cs b/Providers/Dtos/XAiMessageRepositoryService.cs index a006efe..7723416 100644 --- a/Providers/Dtos/XAiMessageRepositoryService.cs +++ b/Providers/Dtos/XAiMessageRepositoryService.cs @@ -1,23 +1,487 @@ using System; using System.Collections.Generic; -using AutoMapper; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Query; +using xAiModels.Configurations; using xAiModels.Interfaces.Dtos; +using xAiModels.Interfaces.Enrichers; using xAiModels.Interfaces.Entities; using xAiModels.Models.Dtos; using xAiModels.Models.Entities; +using xCommons.Extensions; using xDataService.Providers; +using xModels.Dtos; namespace xAiModels.Providers.Dtos { public class XAiMessageRepositoryService : XBaseRepositoryService, IXAiMessageRepositoryService { + private readonly IXAiMessageEnricher enricher; + public XAiMessageRepositoryService( - IXAiMessageRepository repository, - IEnumerable mapperProfiles = null + IXAiMessageEnricher enricher, + IXAiMessageRepository repository ) : base( repository, - mapperProfiles + mapperProfiles: + [ + new XAiModelMappersProfile() + ] ) - { } + { + this.enricher = enricher; + } + + // + #region Actions ... + // + #region Add ... + /// + /// add a new Dto ... + /// + /// + /// + /// + /// + public override async Task AddAsync( + XAiMessageDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.AddAsync( + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// add or update a Dto (add if not exists/update if exists) ... + /// + /// + /// + /// + /// + public override async Task AddOrUpdateAsync( + XAiMessageDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.AddAsync( + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Update ... + /// + /// Update an Dto values ... + /// + /// + /// + /// + /// + /// + public override async Task UpdateAsync( + Guid id, + XAiMessageDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.UpdateAsync( + id: id, + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Remove ... + /// + /// remove an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + public override async Task RemoveAsync( + Guid id, + bool softDelete = true, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.RemoveAsync( + id: id, + softDelete: softDelete, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// remove an Dto ... + /// + /// + /// + /// + /// + /// + public override async Task RemoveAsync( + XAiMessageDto item, + bool softDelete = true, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.RemoveAsync( + item: item, + softDelete: softDelete, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Retrieve ... + /// + /// retrieve an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + public override async Task GetAsync( + Guid id, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.GetAsync( + id: id, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// retrieve all exists Dtos ... + /// + /// + /// + /// + /// + /// + public override async Task> GetAllAsync( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.GetAllAsync( + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result, + destinations: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// retrieve all exists Dtos + /// as Async Enumerable ... + /// + /// + /// + /// + /// + /// + public override async IAsyncEnumerable GetAllAsAsyncEnumerable( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + [EnumeratorCancellation] CancellationToken cancellationToken = default + ) + { + // + var enumerable = base.GetAllAsAsyncEnumerable( + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + await foreach (var dto in enumerable) + { + // + if (cancellationToken.IsCancellationRequested) + { + yield break; + } + + // + await enricher.EnrichAsync( + source: dto, + destination: dto, + cancellationToken: cancellationToken + ); + yield return dto; + } + } + + /// + /// find an Dto by providing a Conditional Expression ... + /// + /// + /// + /// + /// + /// + public override async Task FindOneAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.FindOneAsync( + predicate: predicate, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// find a collection of Dtos by proving a Conditional Expression ... + /// + /// + /// + /// + /// + /// + /// + public override async Task> FindManyAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.FindManyAsync( + predicate: predicate, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result, + destinations: result, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// retrieve Dtos based on XQuery Pagination structure ... + /// + /// + /// + /// + /// + /// + /// + /// + public override 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 base.QueryAsync( + query: query, + predicate: predicate, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result.Items, + destinations: result.Items, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + #endregion } } \ No newline at end of file diff --git a/Providers/Dtos/XAiProjectRepositoryService.cs b/Providers/Dtos/XAiProjectRepositoryService.cs index 1b51a8b..85cc68a 100644 --- a/Providers/Dtos/XAiProjectRepositoryService.cs +++ b/Providers/Dtos/XAiProjectRepositoryService.cs @@ -1,23 +1,803 @@ using System; using System.Collections.Generic; -using AutoMapper; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Query; +using xAiModels.Configurations; using xAiModels.Interfaces.Dtos; +using xAiModels.Interfaces.Enrichers; using xAiModels.Interfaces.Entities; using xAiModels.Models.Dtos; using xAiModels.Models.Entities; +using xCommons.Extensions; using xDataService.Providers; +using xModels.Dtos; namespace xAiModels.Providers.Dtos { public class XAiProjectRepositoryService : XBaseRepositoryService, IXAiProjectRepositoryService { + private readonly IXAiProjectEnricher enricher; + public XAiProjectRepositoryService( - IXAiProjectRepository repository, - IEnumerable mapperProfiles = null + IXAiProjectEnricher enricher, + IXAiProjectRepository repository ) : base( repository, - mapperProfiles + mapperProfiles: + [ + new XAiModelMappersProfile() + ] ) - { } + { + this.enricher = enricher; + } + + + // + #region Actions Base ... + // + #region Add ... + /// + /// add a new Dto ... + /// + /// + /// + /// + /// + public override async Task AddAsync( + XAiProjectDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + return await AddAsync( + item: item, + saveChanges: saveChanges, + fillConversations: false, + cancellationToken: cancellationToken + ); + } + + /// + /// add or update a Dto (add if not exists/update if exists) ... + /// + /// + /// + /// + /// + public override async Task AddOrUpdateAsync( + XAiProjectDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + return await AddOrUpdateAsync( + item: item, + saveChanges: saveChanges, + fillConversations: false, + cancellationToken: cancellationToken + ); + } + #endregion + + // + #region Update ... + /// + /// Update an Dto values ... + /// + /// + /// + /// + /// + /// + public override async Task UpdateAsync( + Guid id, + XAiProjectDto item, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + return await UpdateAsync( + id: id, + item: item, + saveChanges: saveChanges, + fillConversations: false, + cancellationToken: cancellationToken + ); + } + #endregion + + // + #region Remove ... + /// + /// remove an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + public override async Task RemoveAsync( + Guid id, + bool softDelete = false, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + return await RemoveAsync( + id: id, + softDelete: softDelete, + saveChanges: saveChanges, + fillConversations: false, + cancellationToken: cancellationToken + ); + } + + /// + /// remove an Dto ... + /// + /// + /// + /// + /// + /// + public override async Task RemoveAsync( + XAiProjectDto item, + bool softDelete = false, + bool saveChanges = true, + CancellationToken cancellationToken = default + ) + { + return await RemoveAsync( + item: item, + softDelete: softDelete, + saveChanges: saveChanges, + fillConversations: false, + cancellationToken: cancellationToken + ); + } + #endregion + + // + #region Retrieve ... + /// + /// retrieve an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + public override async Task GetAsync( + Guid id, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return await GetAsync( + id: id, + fillConversations: false, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + + /// + /// retrieve all exists Dtos ... + /// + /// + /// + /// + /// + /// + public override async Task> GetAllAsync( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return await GetAllAsync( + fillConversations: false, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + + /// + /// retrieve all exists Dtos + /// as Async Enumerable ... + /// + /// + /// + /// + /// + /// + public override IAsyncEnumerable GetAllAsAsyncEnumerable( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return GetAllAsAsyncEnumerable( + fillConversations: false, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + + /// + /// find an Dto by providing a Conditional Expression ... + /// + /// + /// + /// + /// + /// + public override async Task FindOneAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return await FindOneAsync( + predicate: predicate, + fillConversations: false, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + + /// + /// find a collection of Dtos by proving a Conditional Expression ... + /// + /// + /// + /// + /// + /// + /// + public override async Task> FindManyAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return await FindManyAsync( + predicate: predicate, + fillConversations: false, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + + /// + /// retrieve Dtos based on XQuery Pagination structure ... + /// + /// + /// + /// + /// + /// + /// + /// + public override async Task> QueryAsync( + XQuery query, + bool ignoreSoftDeleteds = true, + Expression> predicate = null, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + CancellationToken cancellationToken = default + ) + { + return await QueryAsync( + query: query, + predicate: predicate, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + } + #endregion + #endregion + + // + #region Actions ... + // + #region Add ... + /// + /// add a new Dto ... + /// + /// + /// + /// + /// + /// + public virtual async Task AddAsync( + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.AddAsync( + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// add or update a Dto (add if not exists/update if exists) ... + /// + /// + /// + /// + /// + /// + public virtual async Task AddOrUpdateAsync( + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.AddAsync( + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Update ... + /// + /// Update an Dto values ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task UpdateAsync( + Guid id, + XAiProjectDto item, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.UpdateAsync( + id: id, + item: item, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Remove ... + /// + /// remove an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task RemoveAsync( + Guid id, + bool softDelete = false, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.RemoveAsync( + id: id, + softDelete: softDelete, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// remove an Dto ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task RemoveAsync( + XAiProjectDto item, + bool softDelete = false, + bool saveChanges = true, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.RemoveAsync( + item: item, + softDelete: softDelete, + saveChanges: saveChanges, + cancellationToken: cancellationToken + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + + // + #region Retrieve ... + /// + /// retrieve an Dto by it's Id ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task GetAsync( + Guid id, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.GetAsync( + id: id, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// retrieve all exists Dtos ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task> GetAllAsync( + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.GetAllAsync( + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result, + destinations: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + 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, + bool fillConversations = true, + [EnumeratorCancellation] CancellationToken cancellationToken = default + ) + { + // + var enumerable = base.GetAllAsAsyncEnumerable( + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + await foreach (var dto in enumerable) + { + // + if (cancellationToken.IsCancellationRequested) + { + yield break; + } + + // + await enricher.EnrichAsync( + source: dto, + destination: dto, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + yield return dto; + } + } + + /// + /// find an Dto by providing a Conditional Expression ... + /// + /// + /// + /// + /// + /// + /// + public virtual async Task FindOneAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.FindOneAsync( + predicate: predicate, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichAsync( + source: result, + destination: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// find a collection of Dtos by proving a Conditional Expression ... + /// + /// + /// + /// + /// + /// + /// + /// + public virtual async Task> FindManyAsync( + Expression> predicate, + bool ignoreSoftDeleteds = true, + Func, IOrderedQueryable> orderBuilder = null, + Func, IIncludableQueryable> includeBuilder = null, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.FindManyAsync( + predicate: predicate, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result, + destinations: result, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + + /// + /// retrieve Dtos 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, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + var result = await base.QueryAsync( + query: query, + predicate: predicate, + orderBuilder: orderBuilder, + includeBuilder: includeBuilder, + cancellationToken: cancellationToken, + ignoreSoftDeleteds: ignoreSoftDeleteds + ); + + // + // Do Enrichment if result Exists ... + if (!result.IsNullOrDefault()) + { + // + await enricher.EnrichRangeAsync( + sources: result.Items, + destinations: result.Items, + fillConversations: fillConversations, + cancellationToken: cancellationToken + ); + } + + // + return result; + } + #endregion + #endregion } } \ No newline at end of file diff --git a/Providers/Enrichers/XAiConversationEnricher.cs b/Providers/Enrichers/XAiConversationEnricher.cs index 18d80ae..d7725d5 100644 --- a/Providers/Enrichers/XAiConversationEnricher.cs +++ b/Providers/Enrichers/XAiConversationEnricher.cs @@ -147,6 +147,7 @@ namespace xAiModels.Providers.Enrichers // result = await conversationTitleResourceProvider.GetResource( + owner: null, identifier: title, cancellationToken: cancellationToken ); diff --git a/Providers/Enrichers/XAiMessageEnricher.cs b/Providers/Enrichers/XAiMessageEnricher.cs index f5c4d5f..3c03cad 100644 --- a/Providers/Enrichers/XAiMessageEnricher.cs +++ b/Providers/Enrichers/XAiMessageEnricher.cs @@ -37,6 +37,7 @@ namespace xAiModels.Providers.Enrichers // Run independent async operations concurrently var ownerTask = ResolveOwnerAsync(source.OwnerId, cancellationToken); var conversationTask = ResolveConversationAsync(source.ConversationId, cancellationToken); + // // wait until All Tasks Resolved ... await Task.WhenAll(ownerTask, conversationTask); diff --git a/Providers/Enrichers/XAiProjectEnricher.cs b/Providers/Enrichers/XAiProjectEnricher.cs index a07bde7..842343b 100644 --- a/Providers/Enrichers/XAiProjectEnricher.cs +++ b/Providers/Enrichers/XAiProjectEnricher.cs @@ -34,22 +34,90 @@ namespace xAiModels.Providers.Enrichers this.projectDescriptionResourceProvider = projectDescriptionResourceProvider; } - public Task EnrichAsync( + public async Task EnrichAsync( XAiProjectDto source, XAiProjectDto destination, CancellationToken cancellationToken = default ) { - throw new NotImplementedException(); + await EnrichAsync( + source: source, + destination: destination, + fillConversations: false, + cancellationToken: cancellationToken + ); } - public Task EnrichRangeAsync( + public async Task EnrichAsync( + XAiProjectDto source, + XAiProjectDto destination, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + // Run independent async operations concurrently + var titleTask = ResolveTitleAsync(source.Title, cancellationToken); + var ownerTask = ResolveOwnerAsync(source.OwnerId, cancellationToken); + var conversationsTask = ResolveConversationsAsync(source.Id, cancellationToken); + var descriptionTask = ResolveDescriptionAsync(source.Description, cancellationToken); + + // + // wait until All Tasks Resolved ... + Task[] tasks = + { + titleTask, + ownerTask, + descriptionTask + }; + if (fillConversations) + { + tasks = [.. tasks, conversationsTask]; + } + await Task.WhenAll(tasks); + + // + // Attached Resolved Info to Destination ... + destination.Owner = ownerTask.Result; + destination.TitleResource = titleTask.Result; + destination.DescriptionResource = descriptionTask.Result; + if (!conversationsTask.Result.IsNull()) + { + destination.Conversations = [.. conversationsTask.Result]; + } + } + + public async Task EnrichRangeAsync( IEnumerable sources, IEnumerable destinations, CancellationToken cancellationToken = default ) { - throw new NotImplementedException(); + // + // Make Tasks Ready ... + var tasks = sources.Zip(destinations, (src, dst) => + EnrichAsync(src, dst, cancellationToken) + ); + + // + await Task.WhenAll(tasks); + } + + public async Task EnrichRangeAsync( + IEnumerable sources, + IEnumerable destinations, + bool fillConversations = true, + CancellationToken cancellationToken = default + ) + { + // + // Make Tasks Ready ... + var tasks = sources.Zip(destinations, (src, dst) => + EnrichAsync(src, dst, fillConversations, cancellationToken) + ); + + // + await Task.WhenAll(tasks); } // @@ -111,6 +179,7 @@ namespace xAiModels.Providers.Enrichers // result = await projectTitleResourceProvider.GetResource( + owner: null, identifier: identifier, cancellationToken: cancellationToken ); @@ -142,6 +211,7 @@ namespace xAiModels.Providers.Enrichers // result = await projectDescriptionResourceProvider.GetResource( + owner: null, identifier: identifier, cancellationToken: cancellationToken ); diff --git a/Providers/XAiConversationTitleResourceProvider.cs b/Providers/XAiConversationTitleResourceProvider.cs index 7747623..5879eab 100644 --- a/Providers/XAiConversationTitleResourceProvider.cs +++ b/Providers/XAiConversationTitleResourceProvider.cs @@ -1,23 +1,21 @@ using xAiModels.Constants; using xAiModels.Interfaces; +using xCommons.Configurations; using xStringService.Interfaces.Dtos; using xStringService.Providers; namespace xAiModels.Providers { - public class XAiConversationTitleResourceProvider : XBaseItemResourceProvider, IXAiConversationTitleResourceProvider + public class XAiConversationTitleResourceProvider : XBaseOwnedItemResourceProvider, IXAiConversationTitleResourceProvider { public XAiConversationTitleResourceProvider( + XAppConfiguration appConfig, IXStringServiceProvider stringProvider ) : base( + appConfig: appConfig, stringProvider: stringProvider, item: XAiModelsConstants.XAiConversationTitleIdentifier ) { } - - // - #region Actions ... - - #endregion } } \ No newline at end of file diff --git a/Providers/XAiProjectDescriptionResourceProvider.cs b/Providers/XAiProjectDescriptionResourceProvider.cs index 58c2b05..92611dd 100644 --- a/Providers/XAiProjectDescriptionResourceProvider.cs +++ b/Providers/XAiProjectDescriptionResourceProvider.cs @@ -1,15 +1,18 @@ using xAiModels.Constants; using xAiModels.Interfaces; +using xCommons.Configurations; using xStringService.Interfaces.Dtos; using xStringService.Providers; namespace xAiModels.Providers { - public class XAiProjectDescriptionResourceProvider : XBaseItemResourceProvider, IXAiProjectDescriptionResourceProvider + public class XAiProjectDescriptionResourceProvider : XBaseOwnedItemResourceProvider, IXAiProjectDescriptionResourceProvider { public XAiProjectDescriptionResourceProvider( + XAppConfiguration appConfig, IXStringServiceProvider stringProvider ) : base( + appConfig: appConfig, stringProvider: stringProvider, item: XAiModelsConstants.XAiProjectDescriptionIdentifier ) diff --git a/Providers/XAiProjectTitleResourceProvider.cs b/Providers/XAiProjectTitleResourceProvider.cs index 3d04d1d..9814e73 100644 --- a/Providers/XAiProjectTitleResourceProvider.cs +++ b/Providers/XAiProjectTitleResourceProvider.cs @@ -1,15 +1,18 @@ using xAiModels.Constants; using xAiModels.Interfaces; +using xCommons.Configurations; using xStringService.Interfaces.Dtos; using xStringService.Providers; namespace xAiModels.Providers { - public class XAiProjectTitleResourceProvider : XBaseItemResourceProvider, IXAiProjectTitleResourceProvider + public class XAiProjectTitleResourceProvider : XBaseOwnedItemResourceProvider, IXAiProjectTitleResourceProvider { public XAiProjectTitleResourceProvider( + XAppConfiguration appConfig, IXStringServiceProvider stringProvider ) : base( + appConfig: appConfig, stringProvider: stringProvider, item: XAiModelsConstants.XAiProjectTitleIdentifier )