2021-02-02 19:32:39 -05:00
|
|
|
|
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
|
|
|
|
|
using PoweredSoft.DynamicQuery;
|
|
|
|
|
using PoweredSoft.DynamicQuery.Core;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace PoweredSoft.CQRS.DynamicQuery
|
|
|
|
|
{
|
|
|
|
|
public abstract class DynamicQueryHandlerBase<TSource, TDestination>
|
|
|
|
|
where TSource : class
|
|
|
|
|
where TDestination : class
|
|
|
|
|
{
|
|
|
|
|
private readonly IQueryHandlerAsync queryHandlerAsync;
|
|
|
|
|
private readonly IEnumerable<IQueryableProvider<TSource>> queryableProviders;
|
2021-02-02 20:06:56 -05:00
|
|
|
|
private readonly IEnumerable<IAlterQueryableService<TSource, TDestination>> alterQueryableServices;
|
2021-02-03 01:26:37 -05:00
|
|
|
|
private readonly IEnumerable<IDynamicQueryInterceptorProvider<TSource, TDestination>> dynamicQueryInterceptorProviders;
|
2021-02-02 20:39:59 -05:00
|
|
|
|
private readonly IServiceProvider serviceProvider;
|
2021-02-02 19:32:39 -05:00
|
|
|
|
|
|
|
|
|
public DynamicQueryHandlerBase(IQueryHandlerAsync queryHandlerAsync,
|
2021-02-02 20:06:56 -05:00
|
|
|
|
IEnumerable<IQueryableProvider<TSource>> queryableProviders,
|
2021-02-02 20:39:59 -05:00
|
|
|
|
IEnumerable<IAlterQueryableService<TSource, TDestination>> alterQueryableServices,
|
2021-02-03 01:26:37 -05:00
|
|
|
|
IEnumerable<IDynamicQueryInterceptorProvider<TSource, TDestination>> dynamicQueryInterceptorProviders,
|
2021-02-02 20:39:59 -05:00
|
|
|
|
IServiceProvider serviceProvider)
|
2021-02-02 19:32:39 -05:00
|
|
|
|
{
|
|
|
|
|
this.queryHandlerAsync = queryHandlerAsync;
|
|
|
|
|
this.queryableProviders = queryableProviders;
|
2021-02-02 20:06:56 -05:00
|
|
|
|
this.alterQueryableServices = alterQueryableServices;
|
2021-02-03 01:26:37 -05:00
|
|
|
|
this.dynamicQueryInterceptorProviders = dynamicQueryInterceptorProviders;
|
2021-02-02 20:39:59 -05:00
|
|
|
|
this.serviceProvider = serviceProvider;
|
2021-02-02 19:32:39 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual Task<IQueryable<TSource>> GetQueryableAsync(IDynamicQuery query, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
if (this.queryableProviders.Any())
|
|
|
|
|
return queryableProviders.ElementAt(0).GetQueryableAsync(query, cancellationToken);
|
|
|
|
|
|
|
|
|
|
throw new Exception($"You must provide a QueryableProvider<TSource> for {typeof(TSource).Name}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual IQueryExecutionOptions GetQueryExecutionOptions(IQueryable<TSource> source, IDynamicQuery query)
|
|
|
|
|
{
|
|
|
|
|
return new QueryExecutionOptions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual IEnumerable<IQueryInterceptor> GetInterceptors()
|
|
|
|
|
{
|
2021-02-03 01:26:37 -05:00
|
|
|
|
var types = dynamicQueryInterceptorProviders.SelectMany(t => t.GetInterceptorsTypes()).Distinct();
|
|
|
|
|
foreach (var type in types)
|
|
|
|
|
yield return serviceProvider.GetService(type) as IQueryInterceptor;
|
2021-02-02 19:32:39 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected async Task<IQueryExecutionResult<TDestination>> ProcessQueryAsync(IDynamicQuery query, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var source = await GetQueryableAsync(query, cancellationToken);
|
|
|
|
|
source = await AlterSourceAsync(source, query, cancellationToken);
|
|
|
|
|
var options = GetQueryExecutionOptions(source, query);
|
|
|
|
|
var interceptors = this.GetInterceptors();
|
|
|
|
|
|
|
|
|
|
foreach (var interceptor in interceptors)
|
|
|
|
|
queryHandlerAsync.AddInterceptor(interceptor);
|
|
|
|
|
|
|
|
|
|
var criteria = CreateCriteriaFromQuery(query);
|
|
|
|
|
var result = await queryHandlerAsync.ExecuteAsync<TSource, TDestination>(source, criteria, options, cancellationToken);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-02 20:06:56 -05:00
|
|
|
|
protected virtual async Task<IQueryable<TSource>> AlterSourceAsync(IQueryable<TSource> source, IDynamicQuery query, CancellationToken cancellationToken)
|
2021-02-02 19:32:39 -05:00
|
|
|
|
{
|
2021-02-02 20:06:56 -05:00
|
|
|
|
foreach (var t in alterQueryableServices)
|
|
|
|
|
source = await t.AlterQueryableAsync(source, query, cancellationToken);
|
|
|
|
|
|
|
|
|
|
return source;
|
2021-02-02 19:32:39 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual IQueryCriteria CreateCriteriaFromQuery(IDynamicQuery query)
|
|
|
|
|
{
|
|
|
|
|
var criteria = new QueryCriteria
|
|
|
|
|
{
|
|
|
|
|
Page = query?.GetPage(),
|
|
|
|
|
PageSize = query?.GetPageSize(),
|
|
|
|
|
Filters = query?.GetFilters() ?? new List<IFilter>(),
|
|
|
|
|
Sorts = query?.GetSorts() ?? new List<ISort>(),
|
|
|
|
|
Groups = query.GetGroups() ?? new List<IGroup>(),
|
|
|
|
|
Aggregates = query.GetAggregates() ?? new List<IAggregate>()
|
|
|
|
|
};
|
|
|
|
|
return criteria;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|