better way to inject interceptors into the dynamic query.

This commit is contained in:
David Lebee
2021-02-03 01:26:37 -05:00
parent d01ac1601c
commit de98b3b472
14 changed files with 263 additions and 73 deletions
@@ -6,15 +6,6 @@ using System.Threading.Tasks;
namespace Demo.DynamicQueries
{
public class SearchContactParamsService : IAlterQueryableService<Contact, Contact, SearchContactParams>
{
public Task<IQueryable<Contact>> AlterQueryableAsync(IQueryable<Contact> query, IDynamicQueryParams<SearchContactParams> dynamicQuery, CancellationToken cancellationToken = default)
{
var safe = dynamicQuery.GetParams()?.SearchDisplayName;
return Task.FromResult(query.Where(t => t.DisplayName.Contains(safe)));
}
}
public class ContactQueryableProvider : IQueryableProvider<Contact>
{
public Task<IQueryable<Contact>> GetQueryableAsync(object query, CancellationToken cancelllationToken = default)
@@ -0,0 +1,18 @@
using Demo.Queries;
using PoweredSoft.DynamicQuery.Core;
using System.Linq;
namespace Demo.DynamicQueries
{
public class PersonConvertInterceptor : IQueryConvertInterceptor<Person, PersonModel>
{
public PersonModel InterceptResultTo(Person entity)
{
return new PersonModel
{
Id = entity.Id,
FullName = entity.FirstName + " " + entity.LastName
};
}
}
}
+10
View File
@@ -0,0 +1,10 @@
using System;
namespace Demo.DynamicQueries
{
public class PersonModel
{
public long Id { get; set; }
public string FullName { get; set; }
}
}
@@ -0,0 +1,54 @@
using Demo.Queries;
using PoweredSoft.DynamicQuery;
using PoweredSoft.DynamicQuery.Core;
using System.Collections.Generic;
namespace Demo.DynamicQueries
{
public class PersonOptimizationInterceptor : IFilterInterceptor, ISortInterceptor
{
public IFilter InterceptFilter(IFilter filter)
{
if (filter is ISimpleFilter simpleFilter)
{
if (simpleFilter.Path.Equals(nameof(PersonModel.FullName), System.StringComparison.InvariantCultureIgnoreCase))
return new CompositeFilter
{
Type = filter.Type,
And = filter.And,
Filters = new List<IFilter> {
new SimpleFilter
{
Not = simpleFilter.Not,
And = false,
Type = simpleFilter.Type,
Value = simpleFilter.Value,
Path = nameof(Person.FirstName)
},
new SimpleFilter
{
Not = simpleFilter.Not,
And = false,
Type = simpleFilter.Type,
Value = simpleFilter.Value,
Path = nameof(Person.LastName)
}
}
};
}
return filter;
}
public IEnumerable<ISort> InterceptSort(IEnumerable<ISort> sort)
{
foreach(var s in sort)
{
if (s.Path.Equals(nameof(PersonModel.FullName), System.StringComparison.InvariantCultureIgnoreCase))
yield return new Sort(nameof(Person.LastName), s.Ascending);
else
yield return s;
}
}
}
}
@@ -0,0 +1,33 @@
using Demo.Queries;
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo.DynamicQueries
{
public class PersonQueryableProvider : IQueryableProvider<Person>
{
private readonly IEnumerable<Person> _persons = new List<Person>()
{
new Person
{
Id = 1,
FirstName = "David",
LastName = "Lebee"
},
new Person
{
Id = 2,
FirstName = "John",
LastName = "Doe"
}
};
public Task<IQueryable<Person>> GetQueryableAsync(object query, CancellationToken cancelllationToken = default)
{
return Task.FromResult(_persons.AsQueryable());
}
}
}
@@ -0,0 +1,16 @@
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo.DynamicQueries
{
public class SearchContactParamsService : IAlterQueryableService<Contact, Contact, SearchContactParams>
{
public Task<IQueryable<Contact>> AlterQueryableAsync(IQueryable<Contact> query, IDynamicQueryParams<SearchContactParams> dynamicQuery, CancellationToken cancellationToken = default)
{
var safe = dynamicQuery.GetParams()?.SearchDisplayName;
return Task.FromResult(query.Where(t => t.DisplayName.Contains(safe)));
}
}
}
+1 -35
View File
@@ -1,9 +1,4 @@
using PoweredSoft.CQRS.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Demo.Queries
{
@@ -18,33 +13,4 @@ namespace Demo.Queries
{
public string Search { get; set; }
}
public class PersonQueryHandler : IQueryHandler<PersonQuery, IQueryable<Person>>
{
private readonly IEnumerable<Person> _persons = new List<Person>()
{
new Person
{
Id = 1,
FirstName = "David",
LastName = "Lebee"
},
new Person
{
Id = 2,
FirstName = "John",
LastName = "Doe"
}
};
public Task<IQueryable<Person>> HandleAsync(PersonQuery query, CancellationToken cancellationToken = default)
{
var ret = _persons.AsQueryable();
if (query != null && !string.IsNullOrEmpty(query.Search))
ret = ret.Where(t => t.FirstName.Contains(query.Search) || t.LastName.Contains(query.Search));
return Task.FromResult(ret);
}
}
}
+29
View File
@@ -0,0 +1,29 @@
using PoweredSoft.CQRS.Abstractions;
using PoweredSoft.CQRS.DynamicQuery.Abstractions;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo.Queries
{
public class PersonQueryHandler : IQueryHandler<PersonQuery, IQueryable<Person>>
{
private readonly IQueryableProvider<Person> queryableProvider;
public PersonQueryHandler(IQueryableProvider<Person> queryableProvider)
{
this.queryableProvider = queryableProvider;
}
public async Task<IQueryable<Person>> HandleAsync(PersonQuery query, CancellationToken cancellationToken = default)
{
var ret = await queryableProvider.GetQueryableAsync(query);
if (query != null && !string.IsNullOrEmpty(query.Search))
ret = ret.Where(t => t.FirstName.Contains(query.Search) || t.LastName.Contains(query.Search));
return ret;
}
}
}
+6
View File
@@ -65,6 +65,12 @@ namespace Demo
services.AddDynamicQuery<Contact>();
services.AddDynamicQueryWithParams<Contact, SearchContactParams>(name: "SearchContacts")
.AddAlterQueryableWithParams<Contact, SearchContactParams, SearchContactParamsService>();
services
.AddTransient<IQueryableProvider<Person>, PersonQueryableProvider>()
.AddDynamicQuery<Person, PersonModel>("People")
.AddDynamicQueryInterceptor<Person, PersonModel, PersonConvertInterceptor>()
.AddDynamicQueryInterceptor<Person, PersonModel, PersonOptimizationInterceptor>();
}
private void AddCommands(IServiceCollection services)