93 lines
3.9 KiB
C#
93 lines
3.9 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using OpenHarbor.CQRS.DynamicQuery.Abstractions;
|
|||
|
using PoweredSoft.DynamicQuery;
|
|||
|
using PoweredSoft.DynamicQuery.Core;
|
|||
|
|
|||
|
namespace OpenHarbor.CQRS.DynamicQuery;
|
|||
|
|
|||
|
public abstract class DynamicQueryHandlerBase<TSource, TDestination>
|
|||
|
where TSource : class
|
|||
|
where TDestination : class
|
|||
|
{
|
|||
|
private readonly IQueryHandlerAsync _queryHandlerAsync;
|
|||
|
private readonly IEnumerable<IQueryableProvider<TSource>> _queryableProviders;
|
|||
|
private readonly IEnumerable<IAlterQueryableService<TSource, TDestination>> _alterQueryableServices;
|
|||
|
private readonly IEnumerable<IDynamicQueryInterceptorProvider<TSource, TDestination>> _dynamicQueryInterceptorProviders;
|
|||
|
private readonly IServiceProvider _serviceProvider;
|
|||
|
|
|||
|
public DynamicQueryHandlerBase(IQueryHandlerAsync queryHandlerAsync,
|
|||
|
IEnumerable<IQueryableProvider<TSource>> queryableProviders,
|
|||
|
IEnumerable<IAlterQueryableService<TSource, TDestination>> alterQueryableServices,
|
|||
|
IEnumerable<IDynamicQueryInterceptorProvider<TSource, TDestination>> dynamicQueryInterceptorProviders,
|
|||
|
IServiceProvider serviceProvider)
|
|||
|
{
|
|||
|
_queryHandlerAsync = queryHandlerAsync;
|
|||
|
_queryableProviders = queryableProviders;
|
|||
|
_alterQueryableServices = alterQueryableServices;
|
|||
|
_dynamicQueryInterceptorProviders = dynamicQueryInterceptorProviders;
|
|||
|
_serviceProvider = serviceProvider;
|
|||
|
}
|
|||
|
|
|||
|
protected virtual Task<IQueryable<TSource>> GetQueryableAsync(IDynamicQuery query, CancellationToken cancellationToken = default)
|
|||
|
{
|
|||
|
if (_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()
|
|||
|
{
|
|||
|
var types = _dynamicQueryInterceptorProviders.SelectMany(t => t.GetInterceptorsTypes()).Distinct();
|
|||
|
foreach (var type in types)
|
|||
|
yield return _serviceProvider.GetService(type) as IQueryInterceptor;
|
|||
|
}
|
|||
|
|
|||
|
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 = 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;
|
|||
|
}
|
|||
|
|
|||
|
protected virtual async Task<IQueryable<TSource>> AlterSourceAsync(IQueryable<TSource> source, IDynamicQuery query, CancellationToken cancellationToken)
|
|||
|
{
|
|||
|
foreach (var t in _alterQueryableServices)
|
|||
|
source = await t.AlterQueryableAsync(source, query, cancellationToken);
|
|||
|
|
|||
|
return source;
|
|||
|
}
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
|