From c977339613de7f350a301a8e84e020e0ae63a5f6 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 28 May 2026 02:31:45 +0330 Subject: [PATCH] last ... --- .../Entities/XTagEntityConfiguration.cs | 15 + Controllers/XTagRepositoryControllerBase.cs | 33 + .../XTagRepositoryProviderControllerBase.cs | 37 ++ Controllers/XTagServiceControllerBase.cs | 446 +------------- .../XTagServiceProviderControllerBase.cs | 38 ++ DI/XDIHelperExtension.cs | 167 ++++- DataHelper/Events/XTagEvents.cs | 9 - Extensions/XModelExtensions.cs | 149 +++++ Extensions/xTagServiceExtension.cs | 85 --- Helpers/.gitkeep | 0 Helpers/XTagServiceHelper.cs | 279 +++++++++ Hubs/XTagEntityHub.cs | 16 - Interfaces/Dtos/IXTagDtoHub.cs | 9 + Interfaces/Dtos/IXTagRepositoryService.cs | 9 + Interfaces/Dtos/IXTagServiceProvider.cs | 10 + Interfaces/Entities/IXTagEntityHub.cs | 8 + .../{IXTagEvents.cs => IXTagKeyGenerator.cs} | 2 +- Interfaces/Entities/IXTagRepositoryEvents.cs | 8 + .../Entities/IXTagRepositoryProvider.cs | 9 + Interfaces/IXBaseTagProvider.cs | 33 +- Interfaces/IXTagProvider.cs | 172 ------ Interfaces/IXTagSeeder.cs | 8 + Interfaces/IXTagServiceControllerActions.cs | 118 ---- Models/Dtos/XTagDto.cs | 7 +- Models/Entities/XTag.cs | 4 +- Providers/Dtos/XTagDtoHub.cs | 16 + Providers/Dtos/XTagRepositoryService.cs | 22 + Providers/Dtos/XTagServiceProvider.cs | 26 + Providers/Entities/XTagEFRepository.cs | 26 + Providers/Entities/XTagEntityHub.cs | 15 + Providers/Entities/XTagInMemoryRepository.cs | 21 + Providers/Entities/XTagKeyGenerator.cs | 9 + Providers/Entities/XTagMongoRepository.cs | 25 + Providers/Entities/XTagRepositoryEvents.cs | 9 + Providers/Entities/XTagRepositoryProvider.cs | 25 + Providers/Entities/XTagSeederBase.cs | 24 + .../GraphQL/XTagGraphQLTypeHelper.cs | 2 +- .../GraphQL/XTagGraphQuery.cs | 2 +- .../GraphQL/XTagGraphSchema.cs | 3 +- .../GraphQL/XTagGraphType.cs | 2 +- Providers/XBaseTagProvider.cs | 441 ++++++++------ Providers/XTagEntityRegisterar.cs | 27 + Providers/XTagProvider.cs | 571 ------------------ README.md | 207 +++++++ xTagService.csproj | 6 +- 45 files changed, 1503 insertions(+), 1647 deletions(-) create mode 100644 Configurations/Entities/XTagEntityConfiguration.cs create mode 100644 Controllers/XTagRepositoryControllerBase.cs create mode 100644 Controllers/XTagRepositoryProviderControllerBase.cs create mode 100644 Controllers/XTagServiceProviderControllerBase.cs delete mode 100644 DataHelper/Events/XTagEvents.cs create mode 100644 Extensions/XModelExtensions.cs delete mode 100644 Extensions/xTagServiceExtension.cs delete mode 100644 Helpers/.gitkeep create mode 100644 Helpers/XTagServiceHelper.cs delete mode 100644 Hubs/XTagEntityHub.cs create mode 100644 Interfaces/Dtos/IXTagDtoHub.cs create mode 100644 Interfaces/Dtos/IXTagRepositoryService.cs create mode 100644 Interfaces/Dtos/IXTagServiceProvider.cs create mode 100644 Interfaces/Entities/IXTagEntityHub.cs rename Interfaces/Entities/{IXTagEvents.cs => IXTagKeyGenerator.cs} (64%) create mode 100644 Interfaces/Entities/IXTagRepositoryEvents.cs create mode 100644 Interfaces/Entities/IXTagRepositoryProvider.cs delete mode 100644 Interfaces/IXTagProvider.cs create mode 100644 Interfaces/IXTagSeeder.cs delete mode 100644 Interfaces/IXTagServiceControllerActions.cs create mode 100644 Providers/Dtos/XTagDtoHub.cs create mode 100644 Providers/Dtos/XTagRepositoryService.cs create mode 100644 Providers/Dtos/XTagServiceProvider.cs create mode 100644 Providers/Entities/XTagEFRepository.cs create mode 100644 Providers/Entities/XTagEntityHub.cs create mode 100644 Providers/Entities/XTagInMemoryRepository.cs create mode 100644 Providers/Entities/XTagKeyGenerator.cs create mode 100644 Providers/Entities/XTagMongoRepository.cs create mode 100644 Providers/Entities/XTagRepositoryEvents.cs create mode 100644 Providers/Entities/XTagRepositoryProvider.cs create mode 100644 Providers/Entities/XTagSeederBase.cs rename {DataHelper => Providers}/GraphQL/XTagGraphQLTypeHelper.cs (93%) rename {DataHelper => Providers}/GraphQL/XTagGraphQuery.cs (92%) rename {DataHelper => Providers}/GraphQL/XTagGraphSchema.cs (86%) rename {DataHelper => Providers}/GraphQL/XTagGraphType.cs (86%) create mode 100644 Providers/XTagEntityRegisterar.cs delete mode 100644 Providers/XTagProvider.cs diff --git a/Configurations/Entities/XTagEntityConfiguration.cs b/Configurations/Entities/XTagEntityConfiguration.cs new file mode 100644 index 0000000..fb6d0c9 --- /dev/null +++ b/Configurations/Entities/XTagEntityConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using xDataService.Providers; +using xTagService.Models.Entities; + +namespace xTagService.Configurations.Entities +{ + public class XTagEntityConfiguration : XBaseEntityTypeConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Tags"); + } + } +} \ No newline at end of file diff --git a/Controllers/XTagRepositoryControllerBase.cs b/Controllers/XTagRepositoryControllerBase.cs new file mode 100644 index 0000000..935dbde --- /dev/null +++ b/Controllers/XTagRepositoryControllerBase.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xDataService.Controllers; +using xDataService.Interfaces; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Controllers +{ + public abstract class XTagRepositoryControllerBase : XBaseRepositoryController, IXBaseRepositoryController + { + protected XTagRepositoryControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + XValidationProvider validationProvider, + IXTagRepository repository, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + validationProvider, + repository, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/Controllers/XTagRepositoryProviderControllerBase.cs b/Controllers/XTagRepositoryProviderControllerBase.cs new file mode 100644 index 0000000..1c19648 --- /dev/null +++ b/Controllers/XTagRepositoryProviderControllerBase.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xIdentityService.Interfaces; +using xPushService.Controllers; +using xPushService.Interfaces; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; +using xTagService.Providers.Entities; + +namespace xTagService.Controllers +{ + public abstract class XTagRepositoryProviderControllerBase : XBaseRepositoryProviderController, IXBaseRepositoryProviderController + { + protected XTagRepositoryProviderControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXTagRepositoryProvider provider, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider, + provider, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/Controllers/XTagServiceControllerBase.cs b/Controllers/XTagServiceControllerBase.cs index 7ed8d11..cd9df43 100644 --- a/Controllers/XTagServiceControllerBase.cs +++ b/Controllers/XTagServiceControllerBase.cs @@ -1,448 +1,34 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Query; using Microsoft.Extensions.Logging; using xCommons.Configurations; -using xCommons.Extensions; using xCommons.Providers; -using xIdentityService.Controllers; -using xIdentityService.Interfaces; -using xModels.Dtos; -using xTagService.Interfaces; +using xDataService.Controllers; +using xDataService.Interfaces; +using xTagService.Interfaces.Dtos; using xTagService.Models.Dtos; using xTagService.Models.Entities; namespace xTagService.Controllers { - /// - /// a Controller base Class which implement based Actions to Provides Tag Provider Access ... - /// - public abstract class XTagServiceControllerBase : XIBaseProviderController, IXTagServiceControllerActions + public abstract class XTagServiceControllerBase : XBaseServiceController, IXBaseServiceController { - // - #region Props ... - public IXTagProvider TagProvider { get; } - #endregion - - // - #region Constructor ... - public XTagServiceControllerBase( - ILogger logger, - IXTagProvider tagProvider, + protected XTagServiceControllerBase( + ILogger logger, XAppConfiguration appConfiguration, - IXIdentityProvider identityProvider, - XValidationProvider validationProvider + XValidationProvider validationProvider, + IXTagRepositoryService repositoryService, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null ) : base( logger, appConfiguration, - identityProvider, - validationProvider + validationProvider, + repositoryService, + defaultOrderBuilder, + defaultIncludeBuilder ) - { - // - TagProvider = tagProvider; - } - #endregion - - // - #region Actions ... - /// - /// Add Tag by Providing Dto ... - /// - /// - /// - [HttpPost("")] - public virtual async Task> Add( - [FromBody] XTagDto model - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - var result = await TagProvider.Add( - model: model, - connectionId: connectionId - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Update Specified Tag ... - /// - /// - /// - /// - [HttpPut("{id}")] - public virtual async Task> Update( - [FromRoute] int id, - [FromBody] XTagDto model - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - var result = await TagProvider.Update( - id: id, - model: model, - connectionId: connectionId - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Remove Specified Tag by ID ... - /// - /// - /// - [HttpDelete("{id}")] - public virtual async Task> Remove( - [FromRoute] int id - ) - { - // - // Do ... - try - { - // - // Retrieve User Info ... - var userInfo = await GetUserInfo(); - var connectionId = GetConnectionId(); - bool isAdmin = userInfo.Roles.Any(r => r.ToNormalString() == "admin"); - var userId = userInfo.UserId; - - // - var result = await TagProvider.Remove( - id: id, - connectionId: connectionId - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Retrieve Specified Tag Dto by ID ... - /// - /// - /// - [HttpGet("{id}")] - public virtual async Task> Get( - [FromRoute] int id - ) - { - // - // Do ... - try - { - // - var result = await TagProvider.Get( - id: id - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Retrieve Specified Tag Dto by it's Label ... - /// - /// - /// - [HttpGet("GetTag")] - public virtual async Task> GetTag( - [FromQuery] string tag - ) - { - // - // Do ... - try - { - // - var result = await TagProvider.GetTag( - tag: tag - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Retrieve All Exists Tags ... - /// - /// - [HttpGet("All")] - public virtual async Task>> GetAll() - { - // - // Do ... - try - { - // - var result = await TagProvider.GetAll(); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Search For Specified Tag by Providing a query on Label ... - /// - /// - /// - [HttpGet("FindOne")] - public virtual async Task> FindOne( - [FromQuery] string query - ) - { - // - // Do ... - try - { - // - Expression> whereClause = t => - !query.IsNullOrEmpty() && - t.Tag.ToNormalString() - .Contains(query.ToNormalString()); - var result = await TagProvider.FindOne( - whereClause: whereClause - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Search For Specified Tags By Providing Query on Labels ... - /// - /// - /// - [HttpGet("FindMany")] - public virtual async Task>> FindMany( - [FromQuery] string query - ) - { - // - // Do ... - try - { - // - Expression> whereClause = t => - !query.IsNullOrEmpty() && - t.Tag.ToNormalString() - .Contains(query.ToNormalString()); - var result = await TagProvider.FindMany( - whereClause: whereClause - ); - - // - return Ok(result - .ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Retrieve Tags based on Query Model ... - /// - /// - /// - [HttpGet("Query")] - public virtual async Task>> Query( - [FromQuery] XQuery query - ) - { - // - // Do ... - try - { - // - var result = await TagProvider - .Query(query); - - // - return Ok(result. - ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Count Exists Tags ... - /// - /// - [HttpGet("Count")] - public virtual async Task> Count() - { - // - // Do ... - try - { - // - var result = await TagProvider - .Count(); - - // - return Ok(result. - ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Check Tag Exists by ID ... - /// - /// - /// - [HttpGet("{id}/IsExists")] - public virtual async Task> IsExists( - [FromRoute] int id - ) - { - // - // Do ... - try - { - // - var result = await TagProvider - .IsExists(id); - - // - return Ok(result. - ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - - /// - /// Check Tag Exists by Providing Label ... - /// - /// - /// - [HttpGet("IsTagExists")] - public virtual async Task> IsTagExists( - [FromQuery] string tag - ) - { - // - // Do ... - try - { - // - var result = await TagProvider - .IsTagExists(tag); - - // - return Ok(result. - ToDynamicObject()); - } - catch (Exception ex) - { - // - var result = GetExceptionActionResult(ex); - return result; - } - } - #endregion + { } } } \ No newline at end of file diff --git a/Controllers/XTagServiceProviderControllerBase.cs b/Controllers/XTagServiceProviderControllerBase.cs new file mode 100644 index 0000000..8803ade --- /dev/null +++ b/Controllers/XTagServiceProviderControllerBase.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore.Query; +using Microsoft.Extensions.Logging; +using xCommons.Configurations; +using xCommons.Providers; +using xIdentityService.Interfaces; +using xPushService.Controllers; +using xPushService.Interfaces; +using xTagService.Interfaces.Dtos; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; +using xTagService.Providers.Dtos; + +namespace xTagService.Controllers +{ + public abstract class XTagServiceProviderControllerBase : XBaseServiceProviderController, IXBaseServiceProviderController + { + protected XTagServiceProviderControllerBase( + ILogger logger, + XAppConfiguration appConfiguration, + IXIdentityProvider identityProvider, + XValidationProvider validationProvider, + IXTagServiceProvider provider, + Func, IOrderedQueryable> defaultOrderBuilder = null, + Func, IIncludableQueryable> defaultIncludeBuilder = null + ) : base( + logger, + appConfiguration, + identityProvider, + validationProvider, + provider, + defaultOrderBuilder, + defaultIncludeBuilder + ) + { } + } +} \ No newline at end of file diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index e53325c..b4885d8 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -1,36 +1,108 @@ using System; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using xCommons.Extensions; +using xCommons.Helpers; +using xDataService.Constants; +using xDataService.Db; +using xDataService.DI; +using xDataService.Models; using xExceptions.Constants; -using xTagService.Interfaces; +using xPushService.DI; +using xPushService.Helpers; +using xTagService.Helpers; +using xTagService.Interfaces.Dtos; using xTagService.Interfaces.Entities; -using xTagService.Providers; +using xTagService.Providers.Dtos; +using xTagService.Providers.Entities; namespace xTagService.DI { public static class XDIHelperExtension { /// - /// Register Module Provided Service on DI + /// Register Service ... /// /// - /// + /// + /// public static void AddXTagService( this IServiceCollection services, - ServiceLifetime lifeTime + XRepositoryType repositoryType, + ServiceLifetime lifeTime = ServiceLifetime.Scoped + ) + { + AddTagService( + contextType: null, + services: services, + lifeTime: lifeTime, + repositoryType: repositoryType + ); + } + + /// + /// Register Service ... + /// + /// + /// + /// + /// + public static void AddXTagService( + this IServiceCollection services, + XRepositoryType repositoryType, + ServiceLifetime lifeTime = ServiceLifetime.Scoped + ) + where TContext : XDbContext + { + AddTagService( + services: services, + lifeTime: lifeTime, + contextType: typeof(TContext), + repositoryType: repositoryType + ); + } + + /// + /// Use XTagService Middleware ... + /// + /// + /// + public static void UseXTagService( + this IApplicationBuilder app, + bool isDevelopmentEnvironment = false ) { // - AddTagService( - services, - lifeTime - ); + #region Using XTag Hubs ... + // + var pushHelper = new XPushServiceHelper(); + + // + pushHelper.AddHub("stringDto"); + pushHelper.AddHub("stringEntity"); + + // + app.UseXPushService(pushHelper); + #endregion + + // + // Using XTag Repository Descriptor ... + if (!descriptor.IsNull()) + { + // + app.UseXRepository( + descriptor: descriptor, + isDevelopmentEnvironment: isDevelopmentEnvironment + ); + } } // #region Private ... + private static XRepositoryDescriptor descriptor = null; + /// - /// a LogTag for XTagService ... + /// a LogTag for Service ... /// private static string XLogTag = "XTagService"; @@ -44,13 +116,17 @@ namespace xTagService.DI } /// - /// Register Push Service ... + /// Register Service ... /// /// + /// + /// /// private static void AddTagService( IServiceCollection services, - ServiceLifetime lifeTime + XRepositoryType repositoryType, + Type contextType = null, + ServiceLifetime lifeTime = ServiceLifetime.Scoped ) { // @@ -62,7 +138,7 @@ namespace xTagService.DI if (!isServicesExists) { // - Log("AddTagService failed, services not provided ..."); + Log("Service Registration failed, services not provided ..."); throw exception; } @@ -72,28 +148,73 @@ namespace xTagService.DI if (!isLifetimeExists) { // - Log("AddTagService failed, lifetime not provided ..."); + Log("Service Registration failed, lifetime not provided ..."); throw exception; } // - // Check String Repository Exists ... - var isRepositoryExists = !services - .GetRegisteredService() - .IsNull(); - if (!isRepositoryExists) + // Validate Repository Type ... + var isRepositoryTypeValid = + (repositoryType == XRepositoryType.EF && + !contextType.IsNull()) || + ((repositoryType == XRepositoryType.Mongo || + repositoryType == XRepositoryType.InMemory) && + contextType.IsNull()); + if (!isRepositoryTypeValid) { // - Log("AddTagService failed, IXTagRepository not provided ..."); + Log("Service Registration failed, Invalid Repository Type and Context Type ..."); throw exception; } // - // Register Main Provider ... - services.Add(new ServiceDescriptor(typeof(IXTagProvider), typeof(XTagProvider), lifeTime)); + // Maske Instance of Repository Descriptor + // Based on Provided Type ... + switch (repositoryType) + { + // + case XRepositoryType.EF: + // + descriptor = typeof(XTagServiceHelper) + .InvokeGenericMethod( + methodName: "GetXTagEFRepositoryDescriptor", + runtimeType: contextType, + args: null + ); + break; + + // + case XRepositoryType.Mongo: + descriptor = XTagServiceHelper.GetXTagMongoRepositoryDescriptor(); + break; + + // + case XRepositoryType.InMemory: + descriptor = XTagServiceHelper.GetXTagInMemoryRepositoryDescriptor(); + break; + } // - Log("AddTagService Succeed ..."); + // Register XTag Repository Descriptor ... + services.AddXRepository( + lifeTime: lifeTime, + descriptor: descriptor + ); + + // + // Register Dto Services ... + services.Add( + new ServiceDescriptor(typeof(IXTagServiceProvider), typeof(XTagServiceProvider), lifeTime) + ); + services.Add( + new ServiceDescriptor(typeof(IXTagRepositoryService), typeof(XTagRepositoryService), lifeTime) + ); + services.Add( + new ServiceDescriptor(typeof(IXTagRepositoryProvider), typeof(XTagRepositoryProvider), lifeTime) + ); + + // + Log("Service Regitration Succeed ..."); } #endregion } diff --git a/DataHelper/Events/XTagEvents.cs b/DataHelper/Events/XTagEvents.cs deleted file mode 100644 index b897cf2..0000000 --- a/DataHelper/Events/XTagEvents.cs +++ /dev/null @@ -1,9 +0,0 @@ -using xDataService.Events; -using xTagService.Interfaces.Entities; -using xTagService.Models.Entities; - -namespace xTagService.DataHelper.Events -{ - public class XTagEvents : XBaseRepositoryEvents, IXTagEvents - { } -} \ No newline at end of file diff --git a/Extensions/XModelExtensions.cs b/Extensions/XModelExtensions.cs new file mode 100644 index 0000000..2182ec2 --- /dev/null +++ b/Extensions/XModelExtensions.cs @@ -0,0 +1,149 @@ +using System.Collections.Generic; +using System.Linq; +using xCommons.Extensions; +using xDataService.Extensions; +using xDataService.Models; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Extensions +{ + public static class XModelExtensions + { + /// + /// Extract References of a Model ... + /// + /// + /// + public static IList> GetReferences( + this XTag source + ) + { + // + var result = new List>(); + + // + if ( + !source.IsNullOrDefault() && + !source.References.IsNullOrEmpty() + ) + { + // + result = source.References + .ParseXReferenceList() + .ToList(); + } + + // + return result; + } + + /// + /// Extract References of a Model ... + /// + /// + /// + public static IList> GetReferences( + this XTagDto source + ) + { + // + var result = new List>(); + + // + if ( + !source.IsNullOrDefault() && + !source.References.IsNullOrEmpty() + ) + { + // + result = source.References + .ParseXReferenceList() + .ToList(); + } + + // + return result; + } + + /// + /// Update a Model's References by Providing References List ... + /// + /// + /// + /// + /// + public static XTag UpdateReferences( + this XTag source, + IList> references, + bool forceClean = true + ) + { + // + XTag result = source; + + // + if (!source.IsNullOrDefault()) + { + // + result = source; + + // + if (forceClean) + { + result.References = string.Empty; + } + + // + if (!references.IsNull() && + references.HasChild()) + { + result.References = references.ToXReferenceString(); + } + } + + // + return result; + } + + /// + /// Update a Model's References by Providing References List ... + /// + /// + /// + /// + /// + public static XTagDto UpdateReferences( + this XTagDto source, + IList> references, + bool forceClean = true + ) + { + // + XTagDto result = source; + + // + if (!source.IsNullOrDefault()) + { + // + result = source; + + // + if (forceClean) + { + result.References = string.Empty; + } + + // + if (!references.IsNull() && + references.HasChild()) + { + result.References = references.ToXReferenceString(); + } + } + + // + return result; + } + } +} \ No newline at end of file diff --git a/Extensions/xTagServiceExtension.cs b/Extensions/xTagServiceExtension.cs deleted file mode 100644 index ea5d28f..0000000 --- a/Extensions/xTagServiceExtension.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using xCommons.Extensions; -using xDataService.Extensions; -using xTagService.Models.Dtos; -using xTagService.Models.Entities; - -namespace xTagService.Extensions -{ - public static class xTagServiceExtension - { - /// - /// Map Global Properties From XFile to XFile Dto ... - /// - /// - /// - public static XTagDto ToDto(this XTag source) - { - // - XTagDto result = null; - - // - if (!source.IsNullOrDefault()) - { - // - result = new XTagDto(); - result = result.UpdateData( - updateWith: source, - propertyBlackList: new List - { - nameof(XTag.Deleted), - nameof(XTag.References), - } - ); - - // - // Preparing List ... - if (!source.References.IsNullOrEmpty()) - { - // - result.References = source.References - .ParseXReferenceList() - .ToList(); - } - } - - // - return result; - } - - /// - /// Converts a Dto to Entity Representation ... - /// Ignore ID Property ... - /// - /// - /// - public static XTag FromDto(this XTagDto source) - { - // - var result = new XTag(); - - // - if (!source.IsNull()) - { - // - result = result.UpdateData( - updateWith: source, - propertyBlackList: new List - { - nameof(XTag.Deleted), - nameof(XTag.References), - } - ); - - // - if (!source.References.IsNull() && source.References.HasChild()) { - result.References = source.References.ToXReferenceString(); - } - } - - // - return result; - } - } -} \ No newline at end of file diff --git a/Helpers/.gitkeep b/Helpers/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/Helpers/XTagServiceHelper.cs b/Helpers/XTagServiceHelper.cs new file mode 100644 index 0000000..63608f5 --- /dev/null +++ b/Helpers/XTagServiceHelper.cs @@ -0,0 +1,279 @@ +using GraphQL.Types; +using xDataService.Db; +using xDataService.Models; +using xDataService.Providers; +using xTagService.Interfaces; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; +using xTagService.Providers.Entities; +using xTagService.Providers.GraphQL; + +namespace xTagService.Helpers +{ + public static class XTagServiceHelper + { + // + #region EF Repository Descriptor Provider(s) ... + public static XEFRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagEFRepository, + TContext + > GetXTagEFRepositoryDescriptor() + where TContext : XDbContext + { + // + var result = new XEFRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagEFRepository, + TContext + >(); + + // + return result; + } + + public static XEFRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagEFRepository, + TContext, + IXTagSeeder, + TSeederImplementation + > GetXTagEFRepositoryDescriptor() + where TContext : XDbContext + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XEFRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagEFRepository, + TContext, + IXTagSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + + // + #region Mongo Repository Descriptor Provider(s) ... + public static XMongoRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagMongoRepository + > GetXTagMongoRepositoryDescriptor() + { + // + var result = new XMongoRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagMongoRepository + >(); + + // + return result; + } + + public static XMongoRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagMongoRepository, + IXTagSeeder, + TSeederImplementation + > GetXTagMongoRepositoryDescriptor() + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XMongoRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagMongoRepository, + IXTagSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + + // + #region InMemory Repository Descriptor Provider(s) ... + public static XInMemoryRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagInMemoryRepository + > GetXTagInMemoryRepositoryDescriptor() + { + // + var result = new XInMemoryRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagInMemoryRepository + >(); + + // + return result; + } + + public static XInMemoryRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagInMemoryRepository, + IXTagSeeder, + TSeederImplementation + > GetXTagInMemoryRepositoryDescriptor() + where TSeederImplementation : XBaseDbSeeder + { + // + var result = new XInMemoryRepositoryDescriptor< + XTag, + int, + IXTagKeyGenerator, + XTagKeyGenerator, + IXTagRepositoryEvents, + XTagRepositoryEvents, + XTagGraphType, + IntGraphType, + XTagGraphQuery, + IXTagGraphQLTypeHelper, + XTagGraphQLTypeHelper, + XTagGraphSchema, + IXTagRepository, + XTagInMemoryRepository, + IXTagSeeder, + TSeederImplementation + >(); + + // + return result; + } + #endregion + } +} \ No newline at end of file diff --git a/Hubs/XTagEntityHub.cs b/Hubs/XTagEntityHub.cs deleted file mode 100644 index 1b3c75c..0000000 --- a/Hubs/XTagEntityHub.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.Extensions.Logging; -using xPushService.Base; -using xTagService.Models.Entities; - -namespace xTagService.Hubs -{ - public class XTagEntityHub : XBaseEntityHub - { - // - #region Constructor ... - public XTagEntityHub(ILogger logger) : base(logger) - { - } - #endregion - } -} \ No newline at end of file diff --git a/Interfaces/Dtos/IXTagDtoHub.cs b/Interfaces/Dtos/IXTagDtoHub.cs new file mode 100644 index 0000000..f525374 --- /dev/null +++ b/Interfaces/Dtos/IXTagDtoHub.cs @@ -0,0 +1,9 @@ +using xPushService.Interfaces; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Interfaces.Dtos +{ + public interface IXTagDtoHub : IXBaseDtoHub + { } +} \ No newline at end of file diff --git a/Interfaces/Dtos/IXTagRepositoryService.cs b/Interfaces/Dtos/IXTagRepositoryService.cs new file mode 100644 index 0000000..d00e0d6 --- /dev/null +++ b/Interfaces/Dtos/IXTagRepositoryService.cs @@ -0,0 +1,9 @@ +using xDataService.Interfaces; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Interfaces.Dtos +{ + public interface IXTagRepositoryService : IXBaseRepositoryService + { } +} \ No newline at end of file diff --git a/Interfaces/Dtos/IXTagServiceProvider.cs b/Interfaces/Dtos/IXTagServiceProvider.cs new file mode 100644 index 0000000..baba355 --- /dev/null +++ b/Interfaces/Dtos/IXTagServiceProvider.cs @@ -0,0 +1,10 @@ +using xPushService.Interfaces; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; +using xTagService.Providers.Dtos; + +namespace xTagService.Interfaces.Dtos +{ + public interface IXTagServiceProvider : IXBaseDtoProvider + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXTagEntityHub.cs b/Interfaces/Entities/IXTagEntityHub.cs new file mode 100644 index 0000000..547db62 --- /dev/null +++ b/Interfaces/Entities/IXTagEntityHub.cs @@ -0,0 +1,8 @@ +using xPushService.Interfaces; +using xTagService.Models.Entities; + +namespace xTagService.Interfaces.Entities +{ + public interface IXTagEntityHub : IXBaseEntityHub + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXTagEvents.cs b/Interfaces/Entities/IXTagKeyGenerator.cs similarity index 64% rename from Interfaces/Entities/IXTagEvents.cs rename to Interfaces/Entities/IXTagKeyGenerator.cs index 45af083..61d7160 100644 --- a/Interfaces/Entities/IXTagEvents.cs +++ b/Interfaces/Entities/IXTagKeyGenerator.cs @@ -3,6 +3,6 @@ using xTagService.Models.Entities; namespace xTagService.Interfaces.Entities { - public interface IXTagEvents: IXBaseRepositoryEvents + public interface IXTagKeyGenerator : IXKeyGenerator { } } \ No newline at end of file diff --git a/Interfaces/Entities/IXTagRepositoryEvents.cs b/Interfaces/Entities/IXTagRepositoryEvents.cs new file mode 100644 index 0000000..936328c --- /dev/null +++ b/Interfaces/Entities/IXTagRepositoryEvents.cs @@ -0,0 +1,8 @@ +using xDataService.Interfaces; +using xTagService.Models.Entities; + +namespace xTagService.Interfaces.Entities +{ + public interface IXTagRepositoryEvents : IXBaseRepositoryEvents + { } +} \ No newline at end of file diff --git a/Interfaces/Entities/IXTagRepositoryProvider.cs b/Interfaces/Entities/IXTagRepositoryProvider.cs new file mode 100644 index 0000000..73ff834 --- /dev/null +++ b/Interfaces/Entities/IXTagRepositoryProvider.cs @@ -0,0 +1,9 @@ +using xPushService.Interfaces; +using xTagService.Models.Entities; +using xTagService.Providers.Entities; + +namespace xTagService.Interfaces.Entities +{ + public interface IXTagRepositoryProvider : IXBaseEntityProvider + { } +} \ No newline at end of file diff --git a/Interfaces/IXBaseTagProvider.cs b/Interfaces/IXBaseTagProvider.cs index d60554a..994c7aa 100644 --- a/Interfaces/IXBaseTagProvider.cs +++ b/Interfaces/IXBaseTagProvider.cs @@ -1,3 +1,4 @@ +using System.Threading; using System.Threading.Tasks; using xDataService.Interfaces; using xDataService.Models; @@ -5,20 +6,8 @@ using xTagService.Models.Dtos; namespace xTagService.Interfaces { - /// - /// Implementing XBaseTagProvider ... - /// - /// public interface IXBaseTagProvider : IXBaseReferencedProvider { - // - #region Props ... - /// - /// Provider Identifier ... - /// - IXTagProvider TagProvider { get; } - #endregion - // #region Tools ... /// @@ -27,11 +16,13 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task AddReference( string tag, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ); /// @@ -40,11 +31,13 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task AddReference( string tag, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ); /// @@ -53,25 +46,29 @@ namespace xTagService.Interfaces /// /// /// + /// /// Task RemoveReference( string tag, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ); /// /// Remove Reference a Tag for Specific XRefence ... /// /// - /// + /// /// + /// /// Task RemoveReference( string tag, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ); - #endregion + #endregion } } \ No newline at end of file diff --git a/Interfaces/IXTagProvider.cs b/Interfaces/IXTagProvider.cs deleted file mode 100644 index d359e62..0000000 --- a/Interfaces/IXTagProvider.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR; -using xDataService.Configuration; -using xIdentityService.Interfaces; -using xModels.Dtos; -using xTagService.Hubs; -using xTagService.Interfaces.Entities; -using xTagService.Models.Dtos; -using xTagService.Models.Entities; - -namespace xTagService.Interfaces -{ - public interface IXTagProvider - { - // - #region Props ... - IXTagRepository Repository { get; } - IHubContext Hub { get; } - IXIdentityProvider IdentityProvider { get; } - XDataServiceConfiguration DataConfiguration { get; } - #endregion - - // - #region Helpers ... - /// - /// Converts an Entity to Dto ... - /// - /// - /// - XTagDto ToDto(XTag model); - - /// - /// Converts a List of Entitiies to List of Dto's ... - /// - /// - /// - IEnumerable ToDtoList(IEnumerable models); - - /// - /// Converts Query Result of Entities to Dto ... - /// - /// - /// - XQueryResult ToDtoQueryResult(XQueryResult queryResult); - #endregion - - // - #region Tools ... - /// - /// Add Specified Tag ... - /// - /// - /// - /// - /// - Task Add( - XTagDto model, - string connectionId = null, - CancellationToken cancellationToken = default - ); - - /// - /// Update Specified Dto ... - /// - /// - /// - /// - /// - Task Update( - int id, - XTagDto model, - string connectionId = null, - CancellationToken cancellationToken = default - ); - - /// - /// Remove Specified Dto ... - /// - /// - /// - /// - Task Remove( - int id, - string connectionId = null, - CancellationToken cancellationToken = default - ); - - /// - /// Retrieve Specified Item as Dto ... - /// - /// - /// - Task Get( - int id, - CancellationToken cancellationToken = default - ); - - /// - /// Retrieve Specified Tag by it's Label ... - /// - /// - /// - Task GetTag( - string tag, - CancellationToken cancellationToken = default - ); - - /// - /// Retrieve All Items as Dto ... - /// - /// - Task> GetAll( - CancellationToken cancellationToken = default - ); - - /// - /// Find Specified Item by Condition ... - /// - /// - /// - Task FindOne( - Expression> whereClause, - CancellationToken cancellationToken = default - ); - - /// - /// Find Many Items based on Conditions ... - /// - /// - /// - Task> FindMany( - Expression> whereClause, - CancellationToken cancellationToken = default - ); - - /// - /// Query Model retrieving Dtos ... - /// - /// - /// - Task> Query( - XQuery query, - Expression> whereClause = null, - CancellationToken cancellationToken = default - ); - - /// - /// Count Exists Entities ... - /// - /// - Task Count(); - - /// - /// Check Entity Exists or not ... - /// - /// - /// - Task IsExists(int id); - - /// - /// Check Tag Exists by Label ... - /// - /// - /// - Task IsTagExists(string tag); - #endregion - } -} \ No newline at end of file diff --git a/Interfaces/IXTagSeeder.cs b/Interfaces/IXTagSeeder.cs new file mode 100644 index 0000000..e91944a --- /dev/null +++ b/Interfaces/IXTagSeeder.cs @@ -0,0 +1,8 @@ +using xDataService.Interfaces; +using xTagService.Models.Entities; + +namespace xTagService.Interfaces +{ + public interface IXTagSeeder : IXBaseDbSeeder + { } +} \ No newline at end of file diff --git a/Interfaces/IXTagServiceControllerActions.cs b/Interfaces/IXTagServiceControllerActions.cs deleted file mode 100644 index e61a75e..0000000 --- a/Interfaces/IXTagServiceControllerActions.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using xModels.Dtos; -using xTagService.Models.Dtos; - -namespace xTagService.Interfaces -{ - public interface IXTagServiceControllerActions - { - // - #region Actions ... - /// - /// Add Tag by Providing Dto ... - /// - /// - /// - Task> Add( - [FromBody] XTagDto model - ); - - /// - /// Retrieve Specified Tag Dto by ID ... - /// - /// - /// - Task> Get( - [FromRoute ]int id - ); - - /// - /// Retrieve Specified Tag Dto by it's Label ... - /// - /// - /// - Task> GetTag( - [FromQuery] string tag - ); - - /// - /// Retrieve All Exists Tags ... - /// - /// - Task>> GetAll(); - - /// - /// Search For Specified Tag by Providing a query on Label ... - /// - /// - /// - Task> FindOne( - [FromQuery] string query - ); - - /// - /// Search For Specified Tags By Providing Query on Labels ... - /// - /// - /// - Task>> FindMany( - [FromQuery] string query - ); - - /// - /// Retrieve Tags based on Query Model ... - /// - /// - /// - Task>> Query( - [FromQuery] XQuery query - ); - - /// - /// Update Specified Tag ... - /// - /// - /// - /// - Task> Update( - [FromRoute] int id, - [FromBody] XTagDto model - ); - - /// - /// Remove Specified Tag by ID ... - /// - /// - /// - Task> Remove( - [FromRoute] int id - ); - - /// - /// Count Exists Tags ... - /// - /// - Task> Count(); - - /// - /// Check Tag Exists by ID ... - /// - /// - /// - Task> IsExists( - [FromRoute] int id - ); - - /// - /// Check Tag Exists by Providing Label ... - /// - /// - /// - Task> IsTagExists( - [FromQuery]string tag - ); - #endregion - } -} \ No newline at end of file diff --git a/Models/Dtos/XTagDto.cs b/Models/Dtos/XTagDto.cs index 60270f8..cd9a34e 100644 --- a/Models/Dtos/XTagDto.cs +++ b/Models/Dtos/XTagDto.cs @@ -1,13 +1,10 @@ -using System.Collections.Generic; -using xDataService.Models; using xModels.Base; namespace xTagService.Models.Dtos { - public class XTagDto : XBaseDto + public class XTagDto : XBaseIntIDEntityDto { - public int Id { get; set; } public string Tag { get; set; } - public IList> References = new List>(); + public string References { get; set; } } } \ No newline at end of file diff --git a/Models/Entities/XTag.cs b/Models/Entities/XTag.cs index 342c454..a7666ec 100644 --- a/Models/Entities/XTag.cs +++ b/Models/Entities/XTag.cs @@ -4,7 +4,7 @@ using xModels.Base; namespace xTagService.Models.Entities { /// - /// Describing References ... + /// a Tag Model ... /// public class XTag : XBaseIntIDEntity { @@ -21,6 +21,6 @@ namespace xTagService.Models.Entities /// Model for Describe ... /// /// - public string References { get; set; } + public string References { get; set; } } } \ No newline at end of file diff --git a/Providers/Dtos/XTagDtoHub.cs b/Providers/Dtos/XTagDtoHub.cs new file mode 100644 index 0000000..01449fb --- /dev/null +++ b/Providers/Dtos/XTagDtoHub.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.Logging; +using xPushService.Base; +using xTagService.Interfaces.Dtos; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Dtos +{ + public class XTagDtoHub : XBaseDtoHub, IXTagDtoHub + { + public XTagDtoHub( + ILogger logger + ) : base(logger) + { } + } +} \ No newline at end of file diff --git a/Providers/Dtos/XTagRepositoryService.cs b/Providers/Dtos/XTagRepositoryService.cs new file mode 100644 index 0000000..3226475 --- /dev/null +++ b/Providers/Dtos/XTagRepositoryService.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using AutoMapper; +using xDataService.Providers; +using xTagService.Interfaces.Dtos; +using xTagService.Interfaces.Entities; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Dtos +{ + public class XTagRepositoryService : XBaseRepositoryService, IXTagRepositoryService + { + public XTagRepositoryService( + IXTagRepository repository, + IEnumerable mapperProfiles = null + ) : base( + repository, + mapperProfiles + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Dtos/XTagServiceProvider.cs b/Providers/Dtos/XTagServiceProvider.cs new file mode 100644 index 0000000..1e074d5 --- /dev/null +++ b/Providers/Dtos/XTagServiceProvider.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.SignalR; +using xDataService.Configuration; +using xIdentityService.Interfaces; +using xPushService.Base; +using xTagService.Interfaces.Dtos; +using xTagService.Models.Dtos; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Dtos +{ + public class XTagServiceProvider : XBaseDtoProvider, IXTagServiceProvider + { + public XTagServiceProvider( + IHubContext hub, + XDataServiceConfiguration dataConfiguration, + IXTagRepositoryService service, + IXIdentityProvider identityProvider = null + ) : base( + hub, + dataConfiguration, + service, + identityProvider + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagEFRepository.cs b/Providers/Entities/XTagEFRepository.cs new file mode 100644 index 0000000..0976483 --- /dev/null +++ b/Providers/Entities/XTagEFRepository.cs @@ -0,0 +1,26 @@ +using xDataService.Configuration; +using xDataService.Db; +using xDataService.Interfaces; +using xDataService.Providers; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagEFRepository : XBaseEFRepository, IXTagRepository + where TContext : XDbContext + { + public XTagEFRepository( + IXUnitOfWorks unitOfWorks, + XDataServiceConfiguration configuration, + IXTagKeyGenerator keyGenerator = null, + IXTagRepositoryEvents baseRepositoryEvents = null + ) : base( + unitOfWorks, + configuration, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagEntityHub.cs b/Providers/Entities/XTagEntityHub.cs new file mode 100644 index 0000000..3c267a5 --- /dev/null +++ b/Providers/Entities/XTagEntityHub.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.Logging; +using xPushService.Base; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagEntityHub : XBaseEntityHub, IXTagEntityHub + { + public XTagEntityHub( + ILogger logger + ) : base(logger) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagInMemoryRepository.cs b/Providers/Entities/XTagInMemoryRepository.cs new file mode 100644 index 0000000..2ecb7be --- /dev/null +++ b/Providers/Entities/XTagInMemoryRepository.cs @@ -0,0 +1,21 @@ +using xDataService.Configuration; +using xDataService.Providers; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagInMemoryRepository : XBaseInMemoryRepository, IXTagRepository + { + public XTagInMemoryRepository( + XDataServiceConfiguration configuration, + IXTagKeyGenerator keyGenerator = null, + IXTagRepositoryEvents baseRepositoryEvents = null + ) : base( + configuration, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagKeyGenerator.cs b/Providers/Entities/XTagKeyGenerator.cs new file mode 100644 index 0000000..77e3196 --- /dev/null +++ b/Providers/Entities/XTagKeyGenerator.cs @@ -0,0 +1,9 @@ +using xDataService.Providers; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagKeyGenerator : XIntKeyGenerator, IXTagKeyGenerator + { } +} \ No newline at end of file diff --git a/Providers/Entities/XTagMongoRepository.cs b/Providers/Entities/XTagMongoRepository.cs new file mode 100644 index 0000000..a2744e1 --- /dev/null +++ b/Providers/Entities/XTagMongoRepository.cs @@ -0,0 +1,25 @@ +using xDataService.Configuration; +using xDataService.Providers; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagMongoRepository : XBaseMongoRepository, IXTagRepository + { + public XTagMongoRepository( + XDataBaseConfiguration dbConfiguration, + XDataServiceConfiguration configuration, + string collectionName = null, + IXTagKeyGenerator keyGenerator = null, + IXTagRepositoryEvents baseRepositoryEvents = null + ) : base( + dbConfiguration, + configuration, + collectionName, + keyGenerator, + baseRepositoryEvents + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagRepositoryEvents.cs b/Providers/Entities/XTagRepositoryEvents.cs new file mode 100644 index 0000000..a8c4245 --- /dev/null +++ b/Providers/Entities/XTagRepositoryEvents.cs @@ -0,0 +1,9 @@ +using xDataService.Providers; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagRepositoryEvents : XBaseRepositoryEvents, IXTagRepositoryEvents + { } +} \ No newline at end of file diff --git a/Providers/Entities/XTagRepositoryProvider.cs b/Providers/Entities/XTagRepositoryProvider.cs new file mode 100644 index 0000000..36f83c8 --- /dev/null +++ b/Providers/Entities/XTagRepositoryProvider.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.SignalR; +using xDataService.Configuration; +using xIdentityService.Interfaces; +using xPushService.Base; +using xTagService.Interfaces.Entities; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public class XTagRepositoryProvider : XBaseEntityProvider, IXTagRepositoryProvider + { + public XTagRepositoryProvider( + IHubContext hub, + IXTagRepository repository, + XDataServiceConfiguration dataConfiguration, + IXIdentityProvider identityProvider = null + ) : base( + hub, + repository, + dataConfiguration, + identityProvider + ) + { } + } +} \ No newline at end of file diff --git a/Providers/Entities/XTagSeederBase.cs b/Providers/Entities/XTagSeederBase.cs new file mode 100644 index 0000000..1daf6e2 --- /dev/null +++ b/Providers/Entities/XTagSeederBase.cs @@ -0,0 +1,24 @@ +using xDataService.Configuration; +using xDataService.Interfaces; +using xDataService.Providers; +using xTagService.Interfaces; +using xTagService.Models.Entities; + +namespace xTagService.Providers.Entities +{ + public abstract class XTagSeederBase : XBaseDbSeeder, IXTagSeeder + { + protected XTagSeederBase( + string entity, + string database, + IXBaseRepository repository, + XDataServiceConfiguration dataServiceConfiguration + ) : base( + entity, + database, + repository, + dataServiceConfiguration + ) + { } + } +} \ No newline at end of file diff --git a/DataHelper/GraphQL/XTagGraphQLTypeHelper.cs b/Providers/GraphQL/XTagGraphQLTypeHelper.cs similarity index 93% rename from DataHelper/GraphQL/XTagGraphQLTypeHelper.cs rename to Providers/GraphQL/XTagGraphQLTypeHelper.cs index 34d9e41..3d662bf 100644 --- a/DataHelper/GraphQL/XTagGraphQLTypeHelper.cs +++ b/Providers/GraphQL/XTagGraphQLTypeHelper.cs @@ -3,7 +3,7 @@ using xDataService.GraphQL; using xTagService.Interfaces.Entities; using xTagService.Models.Entities; -namespace xTagService.DataHelper.GraphQL +namespace xTagService.Providers.GraphQL { public class XTagGraphQLTypeHelper : XBaseGraphQLTypeHelper, IXTagGraphQLTypeHelper { diff --git a/DataHelper/GraphQL/XTagGraphQuery.cs b/Providers/GraphQL/XTagGraphQuery.cs similarity index 92% rename from DataHelper/GraphQL/XTagGraphQuery.cs rename to Providers/GraphQL/XTagGraphQuery.cs index d7c1d78..eced747 100644 --- a/DataHelper/GraphQL/XTagGraphQuery.cs +++ b/Providers/GraphQL/XTagGraphQuery.cs @@ -4,7 +4,7 @@ using xDataService.GraphQL; using xTagService.Interfaces.Entities; using xTagService.Models.Entities; -namespace xTagService.DataHelper.GraphQL +namespace xTagService.Providers.GraphQL { public class XTagGraphQuery : XBaseGraphQLQuery { diff --git a/DataHelper/GraphQL/XTagGraphSchema.cs b/Providers/GraphQL/XTagGraphSchema.cs similarity index 86% rename from DataHelper/GraphQL/XTagGraphSchema.cs rename to Providers/GraphQL/XTagGraphSchema.cs index e4af12e..fff14e1 100644 --- a/DataHelper/GraphQL/XTagGraphSchema.cs +++ b/Providers/GraphQL/XTagGraphSchema.cs @@ -1,7 +1,7 @@ using System; using GraphQL.Types; -namespace xTagService.DataHelper.GraphQL +namespace xTagService.Providers.GraphQL { public class XTagGraphSchema : Schema { @@ -9,5 +9,6 @@ namespace xTagService.DataHelper.GraphQL { Query = (XTagGraphQuery)services.GetService(typeof(XTagGraphQuery)); } + } } \ No newline at end of file diff --git a/DataHelper/GraphQL/XTagGraphType.cs b/Providers/GraphQL/XTagGraphType.cs similarity index 86% rename from DataHelper/GraphQL/XTagGraphType.cs rename to Providers/GraphQL/XTagGraphType.cs index f45f1bc..7a4e441 100644 --- a/DataHelper/GraphQL/XTagGraphType.cs +++ b/Providers/GraphQL/XTagGraphType.cs @@ -1,7 +1,7 @@ using xDataService.GraphQL; using xTagService.Models.Entities; -namespace xTagService.DataHelper.GraphQL +namespace xTagService.Providers.GraphQL { public class XTagGraphType : XBaseGraphObjectType { diff --git a/Providers/XBaseTagProvider.cs b/Providers/XBaseTagProvider.cs index 72d8e1b..871fb46 100644 --- a/Providers/XBaseTagProvider.cs +++ b/Providers/XBaseTagProvider.cs @@ -1,8 +1,7 @@ -using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; -using System.Xml; using xCommons.Extensions; using xDataService.Extensions; using xDataService.Models; @@ -10,6 +9,7 @@ using xExceptions.Constants; using xModels.Dtos; using xTagService.Extensions; using xTagService.Interfaces; +using xTagService.Interfaces.Dtos; using xTagService.Models.Dtos; namespace xTagService.Providers @@ -26,14 +26,14 @@ namespace xTagService.Providers /// /// Tag Provider for Maipulating Tags ... /// - public IXTagProvider TagProvider { get; } + public IXTagServiceProvider TagProvider { get; } #endregion // #region Constructor ... public XBaseTagProvider( string providedFor, - IXTagProvider tagProvider + IXTagServiceProvider tagProvider ) { // @@ -49,10 +49,12 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task GetReference( TKey providedForId, - int forIndex = 0 + int forIndex = 0, + CancellationToken cancellationToken = default ) { // @@ -71,7 +73,11 @@ namespace xTagService.Providers // // Retrieve Last Index ... - var maxIndex = (await GetReferencingIndexes(providedForId)).Max(); + var maxIndex = (await GetReferencingIndexes( + providedForId: providedForId, + cancellationToken: cancellationToken + )) + .Max(); if (forIndex > maxIndex) { XException.NotFound.Throw(); @@ -82,17 +88,18 @@ namespace xTagService.Providers forIndex: forIndex, providedForId: providedForId ); - var entity = TagProvider.Repository - .AsQueryable() - .Where(t => t.References.Contains(indexedIdentifier)) - .FirstOrDefault(); - if (entity.IsNullOrDefault()) + var result = await TagProvider.FindOneAsync( + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken, + predicate: x => x.References.Contains(indexedIdentifier) + ); + if (result.IsNullOrDefault()) { XException.NotFound.Throw(); } // - var result = await Task.FromResult(entity.ToDto()); return result; } @@ -100,8 +107,12 @@ namespace xTagService.Providers /// Retrieve all Exists References of Specific Provided ID ... /// /// + /// /// - public async Task> GetAllReferences(TKey providedForId) + public async Task> GetAllReferences( + TKey providedForId, + CancellationToken cancellationToken = default + ) { // // Validate ... @@ -112,34 +123,28 @@ namespace xTagService.Providers // var identifier = GetProvidedID(providedForId); - var entities = TagProvider.Repository - .AsQueryable() - .Where(t => t.References.Contains(identifier)) - .AsEnumerable(); + var result = await TagProvider.FindManyAsync( + orderBuilder: null, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken, + predicate: x => x.References.Contains(identifier) + ); // - var result = new List(); - foreach (var entity in entities) - { - // - var dto = entity.ToDto(); - if (!dto.IsNullOrDefault()) - { - // - result.Add(dto); - } - } - - // - return await Task.FromResult(result); + return result; } /// /// Extract all Referencing Models for Specified Key ... /// /// + /// /// - public async Task>> GetAllReferencings(TKey providedForId) + public async Task>> GetAllReferencings( + TKey providedForId, + CancellationToken cancellationToken = default + ) { // // Validate ... @@ -154,27 +159,34 @@ namespace xTagService.Providers var identifier = GetProvidedID(providedForId); // - var result = TagProvider.Repository - .AsQueryable() - .Where(te => te.References.Contains(identifier)) - .Select(te => te.References) - .ToList() - .SelectMany(tr => tr.ParseXReferenceList()) - .Where(tr => tr.ProvidedFor == Provider && $"{tr.ReferencedTo}" == $"{providedForId}") - .OrderBy(tr => tr.Index) - .AsEnumerable() - ; + var result = (await TagProvider.FindManyAsync( + orderBuilder: null, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken, + predicate: x => x.References.Contains(identifier) + )) + .Select(x => x.References) + .ToList() + .SelectMany(x => x.ParseXReferenceList()) + .Where(x => x.ProvidedFor == Provider && $"{x.ReferencedTo}" == $"{providedForId}") + .OrderBy(x => x.Index) + .AsEnumerable(); // - return await Task.FromResult(result); + return result; } /// /// Count References ... /// /// + /// /// - public async Task CountReferences(TKey providedForId) + public async Task CountReferences( + TKey providedForId, + CancellationToken cancellationToken = default + ) { // // Validate ... @@ -186,23 +198,29 @@ namespace xTagService.Providers // var identifier = GetProvidedID(providedForId); - var result = TagProvider.Repository - .AsQueryable() - .Where(t => t.References.Contains(identifier)) - .Count(); + var result = (await TagProvider.FindManyAsync( + orderBuilder: null, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken, + predicate: x => x.References.Contains(identifier) + )) + .Count(); // - return await Task.FromResult(result); + return result; } /// /// Retrieve References of Specific Provided ID as Query ... /// /// + /// /// public async Task> QueryReferences( XQuery query, - TKey providedForId + TKey providedForId, + CancellationToken cancellationToken = default ) { // @@ -213,64 +231,15 @@ namespace xTagService.Providers } // - // Normalize ... - query = query.NormalizeQuery(TagProvider.DataConfiguration); - - // - var items = await GetAllReferences(providedForId); - var totalItemsCount = items.Count(); - - // - // Apply Filter ... - if (!query.Filter.IsNullOrEmpty()) - { - // - items = items - .ApplyFilter(query.Filter); - } - int filteredItemsCount = items.Count(); - - // - // Count Pages ... - var totalPagesCount = query.CountPages(totalItemsCount); - var filteredPagesCount = query.CountPages(filteredItemsCount); - - // - // Apply Paging and Sorting ... - if (totalItemsCount > 0 && - filteredItemsCount > 0) - { - // - // Apply Sorting ... - items = items - .ToList() - .ApplySorting( - query.SortBy, - query.IsAscending - ); - - // - // Apply Paging ... - items = items - .ToList() - .ApplyPaging( - query.Page, - query.PageSize - ); - } - - // - // Prepare Result ... - var result = new XQueryResult - { - Page = query.Page, - Items = items.ToList(), - PageSize = query.PageSize, - TotalPages = totalPagesCount, - TotalItems = totalItemsCount, - TotalFilteredPages = filteredPagesCount, - TotalFilteredItems = filteredItemsCount - }; + var identifier = GetProvidedID(providedForId); + var result = await TagProvider.QueryAsync( + query: query, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken, + orderBuilder: x => x.OrderBy(y => y.Id), + predicate: x => x.References.Contains(identifier) + ); // return result; @@ -281,13 +250,14 @@ namespace xTagService.Providers /// /// /// - /// /// + /// /// public async Task AddReference( XTagDto model, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -306,7 +276,7 @@ namespace xTagService.Providers // // Check Model Exists ... - result = await TagProvider.IsExists(model.Id); + result = await TagProvider.IsExistsAsync(model.Id); if (!result) { XException.NotFound.Throw(); @@ -314,17 +284,29 @@ namespace xTagService.Providers // // Update Model by Retrieving ... - model = await TagProvider.Get(model.Id); + model = await TagProvider.GetAsync( + id: model.Id, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken + ); // // Retrieve all References ... - var references = await GetAllReferences(providedForId); + var references = await GetAllReferences( + providedForId: providedForId, + cancellationToken: cancellationToken + ); // // Check isReferenced or not ... - result = references.Any(r => r.Id == model.Id && - r.References.Any(rf => rf.ProvidedFor == Provider && - rf.ReferencedTo == $"{providedForId}")); + result = references + .Any(r => + r.Id == model.Id && + r.GetReferences() + .Any(rf => + rf.ProvidedFor == Provider && + rf.ReferencedTo == $"{providedForId}")); if (result) { return result; @@ -332,21 +314,30 @@ namespace xTagService.Providers // // Here means there is not any reference to ProvidedForId ... - int forIndex = await CountReferences(providedForId); - model.References.Add(new XReference + int forIndex = await CountReferences( + providedForId: providedForId, + cancellationToken: cancellationToken + ); + var modelReferences = model.GetReferences(); + modelReferences.Add(new XReference { Index = forIndex, ProvidedFor = Provider, ReferencedTo = $"{providedForId}" }); + modelReferences = modelReferences + .OrderBy(r => r.Index) + .ToList(); + model = model.UpdateReferences(modelReferences); // // Update Data Base ... - model = await TagProvider - .Update( - id: model.Id, - model: model, - connectionId: connectionId + model = await TagProvider.UpdateAsync( + id: model.Id, + item: model, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken ); result = !model.IsNullOrDefault(); @@ -360,11 +351,13 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task AddReference( XTagDto model, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -384,6 +377,7 @@ namespace xTagService.Providers result = await AddReference( model: model, connectionId: connectionId, + cancellationToken: cancellationToken, providedForId: reference.ReferencedTo ); @@ -397,12 +391,13 @@ namespace xTagService.Providers /// /// /// - /// if null, removes all + /// /// public async Task RemoveReference( XTagDto model, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -418,7 +413,12 @@ namespace xTagService.Providers // // Retrieve Model ... - model = await TagProvider.Get(model.Id); + model = await TagProvider.GetAsync( + id: model.Id, + includeBuilder: null, + ignoreSoftDeleteds: true, + cancellationToken: cancellationToken + ); result = !model.IsNullOrDefault(); if (!result) { @@ -427,11 +427,17 @@ namespace xTagService.Providers // // Reading Referencing Indexes ... - var indexes = await GetReferencingIndexes(providedForId); + var indexes = await GetReferencingIndexes( + providedForId: providedForId, + cancellationToken: cancellationToken + ); // // Check Model Reference to ID ... - var referencesCount = await CountReferences(providedForId); + var referencesCount = await CountReferences( + providedForId: providedForId, + cancellationToken: cancellationToken + ); result = referencesCount == 0; if (result) { @@ -442,9 +448,11 @@ namespace xTagService.Providers // // Check Model is Trully Referenced to ProvidedForId or not ... - var reference = model.References - .FirstOrDefault(r => r.ProvidedFor == Provider && - r.ReferencedTo == $"{providedForId}"); + var reference = model + .GetReferences() + .FirstOrDefault(r => + r.ProvidedFor == Provider && + r.ReferencedTo == $"{providedForId}"); result = !reference.IsNullOrDefault(); if (!result) { @@ -453,17 +461,22 @@ namespace xTagService.Providers // // Remove Referenced Item from Model ... - model.References = model.References - .Where(r => !(r.ProvidedFor == Provider && - r.ReferencedTo == $"{providedForId}")) + var modelReferences = model + .GetReferences() + .Where(r => + !(r.ProvidedFor == Provider && + r.ReferencedTo == $"{providedForId}")) .ToList(); + model = model.UpdateReferences(modelReferences); // // Update DataBase ... - model = await TagProvider.Update( + model = await TagProvider.UpdateAsync( + item: model, id: model.Id, - model: model, - connectionId: connectionId + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken ); // @@ -488,12 +501,14 @@ namespace xTagService.Providers // var dto = await GetReference( forIndex: i, - providedForId: providedForId + providedForId: providedForId, + cancellationToken: cancellationToken ); if (!dto.IsNullOrDefault()) { // - dto.References + var dtoReferences = dto.GetReferences(); + dtoReferences .ToList() .ForEach(iref => { @@ -507,12 +522,15 @@ namespace xTagService.Providers iref.Index = i - 1; } }); + dto = dto.UpdateReferences(dtoReferences); // - dto = await TagProvider.Update( + dto = await TagProvider.UpdateAsync( + item: dto, id: dto.Id, - model: dto, - connectionId: connectionId + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken ); } } @@ -526,13 +544,15 @@ namespace xTagService.Providers /// Remove Reference a Model for Specific XRefence ... /// /// - /// + /// /// + /// /// public async Task RemoveReference( XTagDto model, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -548,6 +568,7 @@ namespace xTagService.Providers var result = await RemoveReference( model: model, connectionId: connectionId, + cancellationToken: cancellationToken, providedForId: reference.ReferencedTo ); @@ -560,10 +581,12 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task RemoveReferences( TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -575,7 +598,10 @@ namespace xTagService.Providers // var result = false; - var references = await GetAllReferences(providedForId); + var references = await GetAllReferences( + providedForId: providedForId, + cancellationToken: cancellationToken + ); if (!references.IsNull() && references.HasChild()) { // @@ -583,16 +609,19 @@ namespace xTagService.Providers { // // Remove Reference ... - reference.References = reference.References + var itemReferences = reference.GetReferences() .Where(r => r.ProvidedFor != Provider || (r.ProvidedFor == Provider && r.ReferencedTo != $"{providedForId}")) .ToList(); - var updatedModel = await TagProvider.Update( - id: reference.Id, - model: reference, - connectionId: connectionId + var updatedModel = reference.UpdateReferences(itemReferences); + updatedModel = await TagProvider.UpdateAsync( + saveChanges: true, + item: updatedModel, + id: updatedModel.Id, + connectionId: connectionId, + cancellationToken: cancellationToken ); if (!updatedModel.IsNullOrDefault()) { @@ -613,13 +642,14 @@ namespace xTagService.Providers /// /// /// - /// /// + /// /// public async Task AddReference( string tag, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -635,7 +665,10 @@ namespace xTagService.Providers // // Check Tag Exists ... - result = IsExists(tag); + result = await IsExists( + tag: tag, + cancellationToken: cancellationToken + ); if (!result) { // @@ -644,9 +677,11 @@ namespace xTagService.Providers { Tag = tag, }; - tagDto = await TagProvider.Add( - model: tagDto, - connectionId: connectionId + tagDto = await TagProvider.AddAsync( + item: tagDto, + saveChanges: true, + connectionId: connectionId, + cancellationToken: cancellationToken ); result = !tagDto.IsNullOrDefault(); if (!result) @@ -656,7 +691,10 @@ namespace xTagService.Providers } // - var dto = GetTagByTag(tag); + var dto = await GetTagByTag( + tag: tag, + cancellationToken: cancellationToken + ); result = !dto.IsNullOrDefault(); if (!result) { @@ -667,7 +705,8 @@ namespace xTagService.Providers result = await AddReference( model: dto, connectionId: connectionId, - providedForId: providedForId + providedForId: providedForId, + cancellationToken: cancellationToken ); // @@ -680,11 +719,13 @@ namespace xTagService.Providers /// /// /// + /// /// public async Task AddReference( string tag, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { // @@ -706,6 +747,7 @@ namespace xTagService.Providers result = await AddReference( tag: tag, connectionId: connectionId, + cancellationToken: cancellationToken, providedForId: reference.ReferencedTo ); @@ -718,21 +760,19 @@ namespace xTagService.Providers /// /// /// - /// if null, removes all /// + /// /// public async Task RemoveReference( string tag, TKey providedForId, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { - // - var result = false; - // // Validate ... - result = + var result = !tag.IsNullOrEmpty() && !providedForId.IsNull(); if (!result) @@ -742,14 +782,20 @@ namespace xTagService.Providers // // Check Tag Exists ... - result = IsExists(tag); + result = await IsExists( + tag: tag, + cancellationToken: cancellationToken + ); if (!result) { XException.NotFound.Throw(); } // - var dto = GetTagByTag(tag); + var dto = await GetTagByTag( + tag: tag, + cancellationToken: cancellationToken + ); result = !dto.IsNullOrDefault(); if (!result) { @@ -760,7 +806,8 @@ namespace xTagService.Providers result = await RemoveReference( model: dto, connectionId: connectionId, - providedForId: providedForId + providedForId: providedForId, + cancellationToken: cancellationToken ); // @@ -771,21 +818,20 @@ namespace xTagService.Providers /// Remove Reference a Tag for Specific XRefence ... /// /// - /// + /// /// + /// /// public async Task RemoveReference( string tag, XReference reference, - string connectionId = null + string connectionId = null, + CancellationToken cancellationToken = default ) { - // - var result = false; - // // Validate ... - result = + var result = !tag.IsNullOrEmpty() && !reference.IsNullOrDefault() && !reference.ReferencedTo.IsNull() && @@ -799,6 +845,7 @@ namespace xTagService.Providers result = await RemoveReference( tag: tag, connectionId: connectionId, + cancellationToken: cancellationToken, providedForId: reference.ReferencedTo ); @@ -839,7 +886,10 @@ namespace xTagService.Providers return result; } - private async Task> GetReferencingIndexes(TKey providedForId) + private async Task> GetReferencingIndexes( + TKey providedForId, + CancellationToken cancellationToken = default + ) { // // Validate ... @@ -852,8 +902,12 @@ namespace xTagService.Providers // var result = new List(); - var referencings = await GetAllReferencings(providedForId); - isValid = !referencings.IsNull() && + var referencings = await GetAllReferencings( + providedForId: providedForId, + cancellationToken: cancellationToken + ); + isValid = + !referencings.IsNull() && referencings.HasChild(); if (!isValid) { @@ -871,7 +925,10 @@ namespace xTagService.Providers return result; } - private XTagDto GetTagByTag(string tag) + private async Task GetTagByTag( + string tag, + CancellationToken cancellationToken = default + ) { // XTagDto result = null; @@ -880,20 +937,21 @@ namespace xTagService.Providers if (!tag.IsNullOrEmpty()) { // - var entity = TagProvider.Repository - .AsQueryable() - .FirstOrDefault(e => e.Tag == tag); - if (!entity.IsNullOrDefault()) - { - result = entity.ToDto(); - } + result = await TagProvider + .FindOneAsync( + predicate: x => x.Tag == tag, + cancellationToken: cancellationToken + ); } // return result; } - private bool IsExists(string tag) + private async Task IsExists( + string tag, + CancellationToken cancellationToken = default + ) { // var result = false; @@ -902,13 +960,16 @@ namespace xTagService.Providers if (!tag.IsNullOrEmpty()) { // - var dto = GetTagByTag(tag); + var dto = await GetTagByTag( + tag: tag, + cancellationToken: cancellationToken + ); result = !dto.IsNullOrDefault(); } // return result; } - #endregion + #endregion } } \ No newline at end of file diff --git a/Providers/XTagEntityRegisterar.cs b/Providers/XTagEntityRegisterar.cs new file mode 100644 index 0000000..91406ec --- /dev/null +++ b/Providers/XTagEntityRegisterar.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using xDataService.Interfaces; +using xDataService.Providers; +using xTagService.Models.Entities; + +namespace xTagService.Providers +{ + public class XTagEntityRegisterar : XBaseEntityRegisterar, IXEntityRegisterar + { + public XTagEntityRegisterar() + : base(nameof(XTagEntityRegisterar)) + { + // + // Add XTag Entity ... + AddEntity(); + } + + /// + /// Configure Entities ... + /// + /// + public override void ConfigureEntities(ModelBuilder modelBuilder) + { + base.ConfigureEntities(modelBuilder); + } + } +} \ No newline at end of file diff --git a/Providers/XTagProvider.cs b/Providers/XTagProvider.cs deleted file mode 100644 index 25b27e6..0000000 --- a/Providers/XTagProvider.cs +++ /dev/null @@ -1,571 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR; -using xCommons.Extensions; -using xDataService.Configuration; -using xExceptions.Constants; -using xIdentityService.Interfaces; -using xModels.Dtos; -using xPushService.Constants; -using xTagService.Extensions; -using xTagService.Hubs; -using xTagService.Interfaces; -using xTagService.Interfaces.Entities; -using xTagService.Models.Dtos; -using xTagService.Models.Entities; - -namespace xTagService.Providers -{ - public class XTagProvider : IXTagProvider - { - // - #region Props ... - public IXTagRepository Repository { get; } - public IHubContext Hub { get; } - public IXIdentityProvider IdentityProvider { get; } - public XDataServiceConfiguration DataConfiguration { get; } - #endregion - - // - #region Constructor ... - public XTagProvider( - IXTagRepository repository, - IXIdentityProvider identityProvider, - XDataServiceConfiguration dataConfiguration, - IHubContext hub = null - ) - { - // - Hub = hub; - Repository = repository; - IdentityProvider = identityProvider; - DataConfiguration = dataConfiguration; - } - #endregion - - // - #region Helpers .... - /// - /// Converts an Entity to Dto ... - /// - /// - /// - public XTagDto ToDto(XTag model) - { - return model.ToDto(); - } - - /// - /// Converts a List of Entitiies to List of Dto's ... - /// - /// - /// - public IEnumerable ToDtoList(IEnumerable models) - { - // - var result = new List(); - - // - if (!models.IsNull() && models.HasChild()) - { - // - foreach (var model in models) - { - // - var dto = ToDto(model); - if (!dto.IsNullOrDefault()) - { - result.Add(dto); - } - } - } - - // - return result; - } - - /// - /// Converts Query Result of Entities to Dto ... - /// - /// - /// - public XQueryResult ToDtoQueryResult(XQueryResult queryResult) - { - // - var result = new XQueryResult(); - - // - if (!queryResult.IsNullOrDefault()) - { - // - result.Page = queryResult.Page; - result.PageSize = queryResult.PageSize; - result.TotalItems = queryResult.TotalItems; - result.TotalPages = queryResult.TotalPages; - result.TotalFilteredItems = queryResult.TotalFilteredItems; - result.TotalFilteredPages = queryResult.TotalFilteredPages; - - // - if (!queryResult.Items.IsNull() && queryResult.Items.HasChild()) - { - result.Items = ToDtoList(queryResult.Items); - } - } - - // - return result; - } - #endregion - - // - #region Tools ... - /// - /// Add Specified Tag ... - /// - /// - /// - /// - public async Task Add( - XTagDto model, - string connectionId = null - ) - { - // - XTagDto result = null; - - // - // Converts to Entity ... - var entity = model.FromDto(); - if (!model.IsNullOrDefault()) - { - // - // Validate ... - if (entity.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - entity = await Repository.AddAsync(entity); - if (entity.IsNullOrDefault()) - { - XException.ActionFailed.Throw(); - } - - // - result = ToDto(entity); - } - - // - if (!result.IsNullOrDefault()) - { - // - await SendPush( - action: XBaseEntityHubAction.Add.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - } - - // - return result; - } - - /// - /// Update Specified Dto ... - /// - /// - /// - /// - /// - /// - public async Task Update( - int id, - XTagDto model, - string connectionId = null - ) - { - // - // Validate ... - var isValid = id.IsValidIntId(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - XTagDto result = null; - - // - // Check Exists ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var entity = await Repository.GetAsync(id); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - var tagEntity = model.FromDto(); - entity = entity.UpdateData( - updateWith: tagEntity, - propertyBlackList: new List - { - nameof(XTagDto.Id), - nameof(XTagDto.References) - } - ); - entity.References = tagEntity.References; - entity = await Repository.UpdateAsync(id, entity); - if (!entity.IsNullOrDefault()) - { - result = ToDto(entity); - } - - // - if (!result.IsNullOrDefault()) - { - // - await SendPush( - action: XBaseEntityHubAction.Update.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - } - - // - return result; - } - - /// - /// Remove Specified Dto ... - /// - /// - /// - /// - public async Task Remove( - int id, - string connectionId = null - ) - { - // - // Validate ... - var isValid = id.IsValidIntId(); - if (!isValid) - { - XException.InvalidArgs.Throw(); - } - - // - // Check Exists ... - isValid = await IsExists(id); - if (!isValid) - { - XException.NotFound.Throw(); - } - - // - var entity = await Repository.RemoveAsync(id); - - // - XTagDto result = null; - if (!entity.IsNullOrDefault()) - { - result = ToDto(entity); - } - - // - if (!result.IsNullOrDefault()) - { - // - await SendPush( - action: XBaseEntityHubAction.Delete.GetStringValue(), - payLoad: entity.ToJSON(camelCase: true), - connectionId: connectionId - ); - } - - // - return result; - } - - /// - /// Retrieve Specified Item as Dto ... - /// - /// - /// - public async Task Get(int id) - { - // - var result = new XTagDto(); - if (!id.IsValidIntId()) - { - XException.InvalidArgs.Throw(); - } - - // - if (id.IsValidIntId()) - { - // - var entity = await Repository.GetAsync(id); - if (entity.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - result = ToDto(entity); - if (result.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - } - - // - return result; - } - - /// - /// Retrieve Specified Tag by it's Label ... - /// - /// - /// - public async Task GetTag(string tag) - { - // - // Validate ... - if (tag.IsNullOrEmpty()) - { - XException.InvalidArgs.Throw(); - } - - // - var result = await FindOne(e => e.Tag.ToNormalString() == tag.ToNormalString()); - if (result.IsNullOrDefault()) - { - XException.NotFound.Throw(); - } - - // - return result; - } - - /// - /// Retrieve All Items as Dto ... - /// - /// - public async Task> GetAll() - { - // - var result = new List(); - - // - var entities = await Repository.GetAllAsync(); - if (!entities.IsNull() && entities.HasChild()) - { - // - result = ToDtoList(entities) - .ToList(); - } - - // - return result; - } - - /// - /// Find Specified Item by Condition ... - /// - /// - /// - public async Task FindOne(Expression> whereClause) - { - // - XTagDto result = null; - - // - var entitiy = await Repository.FindOneAsync(whereClause); - if (!entitiy.IsNullOrDefault()) - { - result = ToDto(entitiy); - } - - // - return result; - } - - /// - /// Find Many Items based on Conditions ... - /// - /// - /// - public async Task> FindMany(Expression> whereClause) - { - // - var result = new List(); - - // - var entities = await Repository.FindManyAsync(whereClause); - if (!entities.IsNull() || entities.HasChild()) - { - // - result = ToDtoList(entities) - .ToList(); - } - - // - return result; - } - - /// - /// Query Model retrieving Dtos ... - /// - /// - /// - public async Task> Query(XQuery query) - { - // - var result = new XQueryResult(); - - // - var queryResult = await Repository.QueryAsync(query); - if (!queryResult.IsNull()) - { - result = ToDtoQueryResult(queryResult); - } - - // - return result; - } - - /// - /// Query Conditional Retrieving Dtos ... - /// - /// - /// - /// - public async Task> ConditionalQuery( - XQuery query, - Expression> whereClause - ) - { - // - var result = new XQueryResult(); - - // - var queryResult = await Repository.ConditionalQueryAsync( - query: query, - whereClause: whereClause - ); - if (!queryResult.IsNull()) - { - result = ToDtoQueryResult(queryResult); - } - - // - return result; - } - - /// - /// Count Exists Entities ... - /// - /// - public async Task Count() - { - return await Repository.CountAsync(); - } - - /// - /// Check Entity Exists or not ... - /// - /// - /// - public async Task IsExists(int id) - { - return await Repository.IsExistsAsync(id); - } - - /// - /// Check Tag Exists by Label ... - /// - /// - /// - public async Task IsTagExists(string tag) - { - // - var result = false; - - // - if (!tag.IsNullOrEmpty()) - { - // - var dto = await FindOne(e => e.Tag.ToNormalString() == tag.ToNormalString()); - result = !dto.IsNullOrDefault(); - } - - // - return result; - } - #endregion - - // - #region Hub Actions ... - /// - /// Send Custom Push Message ... - /// - /// - /// - /// - /// - public async Task SendPush( - string action, - string payLoad, - string connectionId = null - ) - { - // - var actions = new List - { - XBaseEntityHubAction.Add.GetStringValue(), - XBaseEntityHubAction.Update.GetStringValue(), - XBaseEntityHubAction.Delete.GetStringValue(), - XBaseEntityHubAction.AddMany.GetStringValue(), - XBaseEntityHubAction.DeleteMany.GetStringValue(), - XBaseEntityHubAction.UpdateMany.GetStringValue(), - XBaseEntityHubAction.AddOrUpdate.GetStringValue(), - }; - - // - // Validate ... - var isValid = - !Hub.IsNull() && - !action.IsNullOrEmpty() && - actions.Contains(action); - if (!isValid) - { - return; - } - - // - var clients = Hub.Clients.All; - if (!connectionId.IsNullOrEmpty()) - { - clients = Hub.Clients.AllExcept(connectionId); - } - try - { - await clients.SendAsync(action, payLoad, connectionId); - } - catch { } - } - #endregion - } -} \ No newline at end of file diff --git a/README.md b/README.md index be99e96..9fc61ac 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,213 @@ it is a Part of xDashboard on SaherElm IT Center which provides all Tag Related Futures ... +this module has following dependencies : + +- xDataService +- xPushService +- xIdentityService + +for configure and use this Module refer to DI.XDIHelperExtension.cs file. + +## Tag + +is a Global Identitifer which act as semantic value that can be represent some metadata about a data. + +Tags can attach/detach to another Items for Describing Metadata about them. + +**xDashboard** Provides Tag Management tools in this Module for adding this Feature to +applications. + +## Data Persists + +all of Provided features of this Module is works based on Data Persistance. so data models is Very Important. +in this section all Data models explained. + +data manipulation done using **xDataService** provided Features. + +- **XTag**: an Entity Model for Mapping to Tables. +- **XTagDto**: a Data Transfer Object for Representing a Data Model. +- **XTagEntityConfiguration**: a Configuration file for XTag Entity. +- **XTagEntityHub**: a Hub Implementation for XTag Entity Model. +- **XTagDtoHub**: a Hub Implementation for XTagDto Model. +- **XTagEntityRegisterar**: an Implementation class for Dynamically Register XTag Entity in a DbContext. +- **IXTagRepositoryEvents**: an Interface for Repository Events Describing of XTag Entity. +- **XTagRepositoryEvents**: an Implementation for Repository Events of XTag Entity. +- **IXTagKeyGenerator**: an Interface for Describing Key Generator Actions for XTag Entity. +- **XTagKeyGenerator**: an Implementation for Describing Key Generator Actions for XTag Entity. +- **IXTagRepository**: an Interface for Describing XTag Repository Actions. +- **XTagEFRepository**: an Implementation of EF Core based XTag Repository Actions. +- **XTagMongoRepository**: an Implementation of MongoDb based XTag Repository Actions. +- **XTagMongoRepository**: an Implementation of MongoDb based XTag Repository Actions. +- **XTagInMemoryRepository**: an Implementation of InMemory based XTag Repository Actions. +- **IXTagSeeder**: an Interface for Describe XTag DbSeeder actions. +- **XTagSeederBase**: an abstraction of Implementation of XTag DbSeeder actions. +- **IXTagRepositoryProvider**: an Interface for Describing XTag Repository Provider (using Hubs) actions. +- **XTagRepositoryProvider**: an Implementation of XTag Repository Provider (using Hubs) actions. +- **IXTagRepositoryService**: an Interface for Describing XTag Repository Service Actions (using XTagDto). +- **XTagRepositoryService**: an Implementation of XTag Repository Service Actions (using XTagDto). +- **IXTagServiceProvider**: an Interface for Describing XTag Repository Service Actions Provider (using Hubs and XTagDto). +- **XTagServiceProvider**: an Implementation of XTag Repository Service Actions Provider (using Hubs and XTagDto). +- **XTagGraphType**: introduce XTag Data model for GraphQL using. +- **XTagGraphQuery**: introduce Repositry Implementation of XTag model actions as Query Actions for GraphQL using. +- **XTagGraphSchema**: introduce XTag Query Schema for GraphQL using. +- **IXTagGraphQLTypeHelper**: an Interface for Describing XTag GraphQL Type Helper Provided Actions. +- **IXTagGraphQLTypeHelper**: an Implementation of XTag GraphQL Type Helper Provided Actions. + +data presistance almost is a Down Layer works which handled using Service it self. +but in some Used cases of Applications Business Logics, for Manipulating resources you can use above Registered Services by Injecting them. + +## Providers + +this module actually used to act as a base Provider for implementing Features based on it. +for this purpose, provides some Features which described in this section. + +### String Resource Provider + +some services used XTag model for Provide Specially Concept's of Actions. for example Terms and Conditions Services use XTag Persisted Resource for Specified Purpose. + +this Module provides some sort of tools for this purpose. which described in this section. + +#### Data Transfer Models + +this service used some Data Transfer Models for Data Providing. which Described in this section. + +```C# +public class XReference +{ + public int Index { get; set; } + public T ReferencedTo { get; set; } + public string ProvidedFor { get; set; } +} +``` + +#### IXBaseTagProvider + +an interface for Describe Provided Actions of Tag based Service. + +```C# +public interface IXBaseTagProvider : IXBaseReferencedProvider +{ + // + #region Tools ... + /// + /// Add Reference a Tag to Specific Provided ID ... + /// + /// + /// + /// + /// + /// + Task AddReference( + string tag, + TKey providedForId, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Add Reference a Tag to Specific XRefence ... + /// + /// + /// + /// + /// + /// + Task AddReference( + string tag, + XReference reference, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Reference a Tag for Specific Provided ID ... + /// + /// + /// + /// + /// + /// + Task RemoveReference( + string tag, + TKey providedForId, + string connectionId = null, + CancellationToken cancellationToken = default + ); + + /// + /// Remove Reference a Tag for Specific XRefence ... + /// + /// + /// + /// + /// + /// + Task RemoveReference( + string tag, + XReference reference, + string connectionId = null, + CancellationToken cancellationToken = default + ); + #endregion +} +``` + +#### XBaseTagProvider + +an implementation of Provided Actions of Resource based Service. + +```C# +public abstract class XBaseTagProvider : IXBaseTagProvider +{ } +``` + +### Controllers + +there are some abstraction Layer of Controller Implementation for using Provided Services for managing data. + +- **XTagRepositoryControllerBase**: an abstract Controller for Provide Repository Actions (using Entity). +- **XTagRepositoryProviderControllerBase**: an abstract Controller for Provide Repository Actions (using Entity and XEntityHub). +- **XTagServiceControllerBase**: an abstract Controller for Provide Service Actions (using Dto). +- **XTagServiceProviderControllerBase**: an abstract Controller for Provide Service Actions (using Dto and XDtoHub). + +## Implementation + +you have to follow these steps for using this Module. + +- **DI Registration**: in this phase, all Provided Services Registered in DI. +- **Middleware Usage**: in this phase, Service Middlewares Use to Handle Features. + +```C# +public class Startup +{ + // + public void ConfigureServices(IServiceCollection services) + { + ... + // + // Register Tag Service ... + services.AddXTagService( + lifeTime: lifeTime, + repositoryType: xDataService.Constants.XRepositoryType.EF + ); + ... + } + + // + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + ... + // + // Using Tag Service ... + app.UseXTagService( + isDevelopmentEnvironment: isDevelopmentEnvironment + ); + ... + } +} +``` + ## Maintainer Hadi Khazaee asl diff --git a/xTagService.csproj b/xTagService.csproj index e7a6565..8e001d3 100644 --- a/xTagService.csproj +++ b/xTagService.csproj @@ -23,15 +23,15 @@ - + - - + +