diff --git a/Demo/DynamicQueries/ContactQueryableProvider.cs b/Demo/DynamicQueries/ContactQueryableProvider.cs index 1947870..7bb0875 100644 --- a/Demo/DynamicQueries/ContactQueryableProvider.cs +++ b/Demo/DynamicQueries/ContactQueryableProvider.cs @@ -6,6 +6,15 @@ using System.Threading.Tasks; namespace Demo.DynamicQueries { + public class SearchContactParamsService : IAlterQueryableService + { + public Task> AlterQueryableAsync(IQueryable query, IDynamicQueryParams dynamicQuery, CancellationToken cancellationToken = default) + { + var safe = dynamicQuery.GetParams()?.SearchDisplayName; + return Task.FromResult(query.Where(t => t.DisplayName.Contains(safe))); + } + } + public class ContactQueryableProvider : IQueryableProvider { public Task> GetQueryableAsync(object query, CancellationToken cancelllationToken = default) diff --git a/Demo/Startup.cs b/Demo/Startup.cs index 65304e3..52f7d3f 100644 --- a/Demo/Startup.cs +++ b/Demo/Startup.cs @@ -63,7 +63,8 @@ namespace Demo { services.AddTransient, ContactQueryableProvider>(); services.AddDynamicQuery(); - services.AddDynamicQueryWithParams(name: "SearchContacts"); + services.AddDynamicQueryWithParams(name: "SearchContacts") + .AddAlterQueryableWithParams(); } private void AddCommands(IServiceCollection services) diff --git a/PoweredSoft.CQRS.DynamicQuery.Abstractions/IAlterQueryableService.cs b/PoweredSoft.CQRS.DynamicQuery.Abstractions/IAlterQueryableService.cs index 5e183d6..11c6d2f 100644 --- a/PoweredSoft.CQRS.DynamicQuery.Abstractions/IAlterQueryableService.cs +++ b/PoweredSoft.CQRS.DynamicQuery.Abstractions/IAlterQueryableService.cs @@ -2,17 +2,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace PoweredSoft.CQRS.DynamicQuery.Abstractions { public interface IAlterQueryableService { - Task> AlterQueryableAsync(IQueryable query, IDynamicQuery dynamicQuery); + Task> AlterQueryableAsync(IQueryable query, IDynamicQuery dynamicQuery, CancellationToken cancellationToken = default); } public interface IAlterQueryableService where TParams : class { - Task> AlterQueryableAsync(IQueryable query, IDynamicQueryParams dynamicQuery); + Task> AlterQueryableAsync(IQueryable query, IDynamicQueryParams dynamicQuery, CancellationToken cancellationToken = default); } } diff --git a/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandler.cs b/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandler.cs index 9c38351..f74fff1 100644 --- a/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandler.cs +++ b/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandler.cs @@ -1,6 +1,7 @@ using PoweredSoft.CQRS.DynamicQuery.Abstractions; using PoweredSoft.DynamicQuery.Core; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -12,7 +13,9 @@ namespace PoweredSoft.CQRS.DynamicQuery where TSource : class where TDestination : class { - public DynamicQueryHandler(IQueryHandlerAsync queryHandlerAsync, IEnumerable> queryableProviders) : base(queryHandlerAsync, queryableProviders) + public DynamicQueryHandler(IQueryHandlerAsync queryHandlerAsync, + IEnumerable> queryableProviders, + IEnumerable> alterQueryableServices) : base(queryHandlerAsync, queryableProviders, alterQueryableServices) { } @@ -29,8 +32,27 @@ namespace PoweredSoft.CQRS.DynamicQuery where TDestination : class where TParams : class { - public DynamicQueryHandler(IQueryHandlerAsync queryHandlerAsync, IEnumerable> queryableProviders) : base(queryHandlerAsync, queryableProviders) + private readonly IEnumerable> alterQueryableServicesWithParams; + + public DynamicQueryHandler(IQueryHandlerAsync queryHandlerAsync, + IEnumerable> queryableProviders, + IEnumerable> alterQueryableServices, + IEnumerable> alterQueryableServicesWithParams) : base(queryHandlerAsync, queryableProviders, alterQueryableServices) { + this.alterQueryableServicesWithParams = alterQueryableServicesWithParams; + } + + protected override async Task> AlterSourceAsync(IQueryable source, IDynamicQuery query, CancellationToken cancellationToken) + { + source = await base.AlterSourceAsync(source, query, cancellationToken); + + if (query is IDynamicQueryParams withParams) + { + foreach (var it in alterQueryableServicesWithParams) + source = await it.AlterQueryableAsync(source, withParams, cancellationToken); + } + + return source; } public Task> HandleAsync(IDynamicQuery query, CancellationToken cancellationToken = default) diff --git a/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandlerBase.cs b/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandlerBase.cs index 07c1581..0f5170e 100644 --- a/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandlerBase.cs +++ b/PoweredSoft.CQRS.DynamicQuery/DynamicQueryHandlerBase.cs @@ -15,12 +15,15 @@ namespace PoweredSoft.CQRS.DynamicQuery { private readonly IQueryHandlerAsync queryHandlerAsync; private readonly IEnumerable> queryableProviders; + private readonly IEnumerable> alterQueryableServices; public DynamicQueryHandlerBase(IQueryHandlerAsync queryHandlerAsync, - IEnumerable> queryableProviders) + IEnumerable> queryableProviders, + IEnumerable> alterQueryableServices) { this.queryHandlerAsync = queryHandlerAsync; this.queryableProviders = queryableProviders; + this.alterQueryableServices = alterQueryableServices; } protected virtual Task> GetQueryableAsync(IDynamicQuery query, CancellationToken cancellationToken = default) @@ -56,9 +59,12 @@ namespace PoweredSoft.CQRS.DynamicQuery return result; } - protected virtual Task> AlterSourceAsync(IQueryable source, IDynamicQuery query, CancellationToken cancellationToken) + protected virtual async Task> AlterSourceAsync(IQueryable source, IDynamicQuery query, CancellationToken cancellationToken) { - return Task.FromResult(source); + foreach (var t in alterQueryableServices) + source = await t.AlterQueryableAsync(source, query, cancellationToken); + + return source; } protected virtual IQueryCriteria CreateCriteriaFromQuery(IDynamicQuery query)