diff --git a/PoweredSoft.DynamicQuery.Cli/Program.cs b/PoweredSoft.DynamicQuery.Cli/Program.cs index c010b23..552a5ed 100644 --- a/PoweredSoft.DynamicQuery.Cli/Program.cs +++ b/PoweredSoft.DynamicQuery.Cli/Program.cs @@ -119,7 +119,7 @@ namespace PoweredSoft.DynamicQuery.Cli new Aggregate { Path = "AgeStr", Type = AggregateType.Avg } };; - var handler = new QueryHandler(); + var handler = new QueryHandler(Enumerable.Empty()); handler.AddInterceptor(new PersonQueryInterceptor()); var result = handler.Execute(queryable, criteria); diff --git a/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs b/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs index 032176e..7bbdd2b 100644 --- a/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs +++ b/PoweredSoft.DynamicQuery.Core/IQueryHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; @@ -9,6 +10,7 @@ namespace PoweredSoft.DynamicQuery.Core public interface IInterceptableQueryHandler { void AddInterceptor(IQueryInterceptor interceptor); + IReadOnlyList ResolveInterceptors(IQueryCriteria criteria, IQueryable queryable); } public interface IQueryHandler : IInterceptableQueryHandler diff --git a/PoweredSoft.DynamicQuery.Core/IQueryInterceptorProvider.cs b/PoweredSoft.DynamicQuery.Core/IQueryInterceptorProvider.cs new file mode 100644 index 0000000..c6d3f97 --- /dev/null +++ b/PoweredSoft.DynamicQuery.Core/IQueryInterceptorProvider.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using System.Linq; + +namespace PoweredSoft.DynamicQuery.Core +{ + public interface IQueryInterceptorProvider + { + IEnumerable GetInterceptors(IQueryCriteria queryCriteria, IQueryable queryable); + } +} diff --git a/PoweredSoft.DynamicQuery.Test/AggregateInterceptorTests.cs b/PoweredSoft.DynamicQuery.Test/AggregateInterceptorTests.cs index 423f0a3..8859173 100644 --- a/PoweredSoft.DynamicQuery.Test/AggregateInterceptorTests.cs +++ b/PoweredSoft.DynamicQuery.Test/AggregateInterceptorTests.cs @@ -38,7 +38,7 @@ namespace PoweredSoft.DynamicQuery.Test Type = AggregateType.Avg, Path = "ItemPrice" }); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockAggregateInterceptor()); var result = queryHandler.Execute(ctx.Items, criteria); Assert.Equal(expected.PriceAtTheTime, result.Aggregates.First().Value); diff --git a/PoweredSoft.DynamicQuery.Test/AggregateTests.cs b/PoweredSoft.DynamicQuery.Test/AggregateTests.cs index d1df1af..145b531 100644 --- a/PoweredSoft.DynamicQuery.Test/AggregateTests.cs +++ b/PoweredSoft.DynamicQuery.Test/AggregateTests.cs @@ -56,7 +56,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.OrderItems, criteria, new QueryExecutionOptions { GroupByInMemory = true @@ -122,7 +122,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var queryable = ctx.OrderItems.Include(t => t.Order); var result = queryHandler.Execute(queryable, criteria, new QueryExecutionOptions { diff --git a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs index e1e5f68..5d15a5f 100644 --- a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs +++ b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs @@ -27,7 +27,7 @@ namespace PoweredSoft.DynamicQuery.Test // query handler that is empty should be the same as running to list. var aqf = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); var criteria = new QueryCriteria(); - var queryHandler = new QueryHandlerAsync(aqf); + var queryHandler = new QueryHandlerAsync(aqf, Enumerable.Empty()); var result = await queryHandler.ExecuteAsync(queryable, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -66,7 +66,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); - var queryHandler = new QueryHandlerAsync(asyncService); + var queryHandler = new QueryHandlerAsync(asyncService, Enumerable.Empty()); var result = await queryHandler.ExecuteAsync(ctx.OrderItems.Include(t => t.Order.Customer), criteria, new QueryExecutionOptions { GroupByInMemory = true @@ -118,7 +118,7 @@ namespace PoweredSoft.DynamicQuery.Test }; var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); - var queryHandler = new QueryHandlerAsync(asyncService); + var queryHandler = new QueryHandlerAsync(asyncService, Enumerable.Empty()); var result = await queryHandler.ExecuteAsync(ctx.Items, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -146,7 +146,7 @@ namespace PoweredSoft.DynamicQuery.Test }; var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); - var queryHandler = new QueryHandlerAsync(asyncService); + var queryHandler = new QueryHandlerAsync(asyncService, Enumerable.Empty()); var result = await queryHandler.ExecuteAsync(ctx.Items, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -166,7 +166,7 @@ namespace PoweredSoft.DynamicQuery.Test criteria.PageSize = 5; var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); - var queryHandler = new QueryHandlerAsync(asyncService); + var queryHandler = new QueryHandlerAsync(asyncService, Enumerable.Empty()); var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -205,7 +205,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); - var queryHandler = new QueryHandlerAsync(asyncService); + var queryHandler = new QueryHandlerAsync(asyncService, Enumerable.Empty()); queryHandler.AddInterceptor(new MockQueryExecutionOptionsInterceptor()); var result = await queryHandler.ExecuteAsync(ctx.OrderItems.Include(t => t.Order.Customer), criteria); diff --git a/PoweredSoft.DynamicQuery.Test/BeforeFilterTests.cs b/PoweredSoft.DynamicQuery.Test/BeforeFilterTests.cs index 67f339b..536277f 100644 --- a/PoweredSoft.DynamicQuery.Test/BeforeFilterTests.cs +++ b/PoweredSoft.DynamicQuery.Test/BeforeFilterTests.cs @@ -50,7 +50,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = (IQueryable)interceptor.InterceptBeforeFiltering(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); @@ -75,7 +75,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = interceptor.InterceptBeforeFiltering(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); diff --git a/PoweredSoft.DynamicQuery.Test/ConvertibleInterceptorTests.cs b/PoweredSoft.DynamicQuery.Test/ConvertibleInterceptorTests.cs index 0533d7c..7ad0bf2 100644 --- a/PoweredSoft.DynamicQuery.Test/ConvertibleInterceptorTests.cs +++ b/PoweredSoft.DynamicQuery.Test/ConvertibleInterceptorTests.cs @@ -2,6 +2,7 @@ using PoweredSoft.DynamicQuery.Test.Mock; using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Xunit; @@ -77,7 +78,7 @@ namespace PoweredSoft.DynamicQuery.Test MockContextFactory.SeedAndTestContextFor("QueryConvertInterceptorTests_NonGeneric", TestSeeders.SimpleSeedScenario, ctx => { var criteria = new QueryCriteria(); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockQueryConvertInterceptor()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.All(result.Data, t => Assert.IsType(t)); @@ -90,7 +91,7 @@ namespace PoweredSoft.DynamicQuery.Test MockContextFactory.SeedAndTestContextFor("ConvertibleIntereceptorTests_Generic", TestSeeders.SimpleSeedScenario, ctx => { var criteria = new QueryCriteria(); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockQueryConvertGenericInterceptor()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.All(result.Data, t => Assert.IsType(t)); @@ -103,7 +104,7 @@ namespace PoweredSoft.DynamicQuery.Test MockContextFactory.SeedAndTestContextFor("ConvertibleIntereceptorTests_Generic2", TestSeeders.SimpleSeedScenario, ctx => { var criteria = new QueryCriteria(); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockQueryConvertGenericInterceptor2()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.All(result.Data, t => Assert.IsType(t)); diff --git a/PoweredSoft.DynamicQuery.Test/CriteriaTests.cs b/PoweredSoft.DynamicQuery.Test/CriteriaTests.cs index b60ced3..a8ed590 100644 --- a/PoweredSoft.DynamicQuery.Test/CriteriaTests.cs +++ b/PoweredSoft.DynamicQuery.Test/CriteriaTests.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; +using PoweredSoft.DynamicQuery.Core; using PoweredSoft.DynamicQuery.Test.Mock; using Xunit; @@ -19,7 +20,7 @@ namespace PoweredSoft.DynamicQuery.Test // query handler that is empty should be the same as running to list. var criteria = new QueryCriteria(); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(queryable, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -38,7 +39,7 @@ namespace PoweredSoft.DynamicQuery.Test criteria.Page = 2; criteria.PageSize = 5; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.OrderItems, criteria); Assert.Equal(resultShouldMatch, result.Data); }); diff --git a/PoweredSoft.DynamicQuery.Test/FilterInterceptorTests.cs b/PoweredSoft.DynamicQuery.Test/FilterInterceptorTests.cs index e49b5be..e4d7280 100644 --- a/PoweredSoft.DynamicQuery.Test/FilterInterceptorTests.cs +++ b/PoweredSoft.DynamicQuery.Test/FilterInterceptorTests.cs @@ -58,7 +58,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var query = new QueryHandler(); + var query = new QueryHandler(Enumerable.Empty()); query.AddInterceptor(new MockFilterInterceptorA()); var result = query.Execute(queryable, criteria); @@ -83,7 +83,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var query = new QueryHandler(); + var query = new QueryHandler(Enumerable.Empty()); query.AddInterceptor(new MockFilterInterceptorAWithExtension()); var result = query.Execute(queryable, criteria); @@ -108,7 +108,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var query = new QueryHandler(); + var query = new QueryHandler(Enumerable.Empty()); query.AddInterceptor(new MockFilterInterceptorAWithExtension()); var result = query.Execute(queryable, criteria); @@ -133,7 +133,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var query = new QueryHandler(); + var query = new QueryHandler(Enumerable.Empty()); query.AddInterceptor(new MockFilterInterceptorA()); query.AddInterceptor(new MockFilterInterceptorB()); var result = query.Execute(queryable, criteria); diff --git a/PoweredSoft.DynamicQuery.Test/FilterTests.cs b/PoweredSoft.DynamicQuery.Test/FilterTests.cs index 0e1d0e7..fdc918f 100644 --- a/PoweredSoft.DynamicQuery.Test/FilterTests.cs +++ b/PoweredSoft.DynamicQuery.Test/FilterTests.cs @@ -32,7 +32,7 @@ namespace PoweredSoft.DynamicQuery.Test Filters = new List { new MockIsChuckFilter() } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -58,7 +58,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Items, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -89,7 +89,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -125,7 +125,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Customers, criteria); Assert.Equal(resultShouldMatch, result.Data); }); diff --git a/PoweredSoft.DynamicQuery.Test/GroupInterceptorTests.cs b/PoweredSoft.DynamicQuery.Test/GroupInterceptorTests.cs index bf3fb8a..b222397 100644 --- a/PoweredSoft.DynamicQuery.Test/GroupInterceptorTests.cs +++ b/PoweredSoft.DynamicQuery.Test/GroupInterceptorTests.cs @@ -36,7 +36,7 @@ namespace PoweredSoft.DynamicQuery.Test var criteria = new QueryCriteria(); criteria.Groups.Add(new Group { Path = "CustomerFirstName" }); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockGroupInterceptor()); var result = queryHandler.Execute(ctx.Orders.Include(t => t.Customer), criteria, new QueryExecutionOptions { @@ -52,7 +52,7 @@ namespace PoweredSoft.DynamicQuery.Test [Fact] public void WithInterptorSimple() { - MockContextFactory.SeedAndTestContextFor("GroupInterceptorTests_Simple", TestSeeders.SimpleSeedScenario, ctx => + MockContextFactory.SeedAndTestContextFor("GroupInterceptorTests_WithInterptorSimple", TestSeeders.SimpleSeedScenario, ctx => { var expected = ctx.Orders .OrderBy(t => t.Customer.FirstName) @@ -62,7 +62,7 @@ namespace PoweredSoft.DynamicQuery.Test var criteria = new QueryCriteria(); criteria.Groups.Add(new Group { Path = "CustomerFirstName" }); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockGroupInterceptor()); queryHandler.AddInterceptor(new MockQueryExecutionOptionsInterceptor()); var result = queryHandler.Execute(ctx.Orders.Include(t => t.Customer), criteria); diff --git a/PoweredSoft.DynamicQuery.Test/GroupTests.cs b/PoweredSoft.DynamicQuery.Test/GroupTests.cs index 591930b..ad0a06a 100644 --- a/PoweredSoft.DynamicQuery.Test/GroupTests.cs +++ b/PoweredSoft.DynamicQuery.Test/GroupTests.cs @@ -39,7 +39,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Orders, criteria, new QueryExecutionOptions { GroupByInMemory = true, @@ -80,7 +80,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Tickets, criteria, new QueryExecutionOptions { GroupByInMemory = true @@ -117,7 +117,7 @@ namespace PoweredSoft.DynamicQuery.Test }; var interceptor = new InterceptorsWithGrouping(); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Tickets, criteria, new QueryExecutionOptions { diff --git a/PoweredSoft.DynamicQuery.Test/IncludeStrategyTests.cs b/PoweredSoft.DynamicQuery.Test/IncludeStrategyTests.cs index 64133ce..74694c1 100644 --- a/PoweredSoft.DynamicQuery.Test/IncludeStrategyTests.cs +++ b/PoweredSoft.DynamicQuery.Test/IncludeStrategyTests.cs @@ -51,7 +51,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = (IQueryable)interceptor.InterceptIncludeStrategy(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); @@ -76,7 +76,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = interceptor.InterceptIncludeStrategy(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); diff --git a/PoweredSoft.DynamicQuery.Test/NoSortTests.cs b/PoweredSoft.DynamicQuery.Test/NoSortTests.cs index e064917..b5f4b2b 100644 --- a/PoweredSoft.DynamicQuery.Test/NoSortTests.cs +++ b/PoweredSoft.DynamicQuery.Test/NoSortTests.cs @@ -51,7 +51,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = (IQueryable)interceptor.InterceptNoSort(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); @@ -76,7 +76,7 @@ namespace PoweredSoft.DynamicQuery.Test queryable = interceptor.InterceptNoSort(criteria, queryable); // query handler should pass by the same interceptor. - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(interceptor); var result = queryHandler.Execute(ctx.Orders, criteria); diff --git a/PoweredSoft.DynamicQuery.Test/QueryProviderTests.cs b/PoweredSoft.DynamicQuery.Test/QueryProviderTests.cs new file mode 100644 index 0000000..acb8179 --- /dev/null +++ b/PoweredSoft.DynamicQuery.Test/QueryProviderTests.cs @@ -0,0 +1,44 @@ +using PoweredSoft.DynamicQuery.Core; +using PoweredSoft.DynamicQuery.Test.Mock; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Xunit; + +namespace PoweredSoft.DynamicQuery.Test +{ + public class QueryProviderTests + { + private class FakeInterceptor : IQueryInterceptor + { + + } + + private class QueryInterceptorProvider : IQueryInterceptorProvider + { + public IEnumerable GetInterceptors(IQueryCriteria queryCriteria, IQueryable queryable) + { + yield return new FakeInterceptor(); + yield return new FakeInterceptor(); + } + } + + [Fact] + public void Simple() + { + MockContextFactory.SeedAndTestContextFor("QueryProviderTests_Simple", TestSeeders.SimpleSeedScenario, ctx => + { + // criteria + var criteria = new QueryCriteria(); + var queryHandler = new QueryHandler(new List{ + new QueryInterceptorProvider() + }); + queryHandler.AddInterceptor(new FakeInterceptor()); + var interceptors = queryHandler.ResolveInterceptors(criteria, ctx.Orders); + Assert.Equal(1, interceptors.Count); + Assert.True(interceptors[0].GetType() == typeof(FakeInterceptor)); + }); + } + } +} diff --git a/PoweredSoft.DynamicQuery.Test/SortInterceptorTests.cs b/PoweredSoft.DynamicQuery.Test/SortInterceptorTests.cs index 9217f22..a70f2b1 100644 --- a/PoweredSoft.DynamicQuery.Test/SortInterceptorTests.cs +++ b/PoweredSoft.DynamicQuery.Test/SortInterceptorTests.cs @@ -33,7 +33,7 @@ namespace PoweredSoft.DynamicQuery.Test // criteria var criteria = new QueryCriteria(); criteria.Sorts.Add(new Sort("CustomerFullName")); - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockSortInterceptor()); var result = queryHandler.Execute(ctx.Orders, criteria); Assert.Equal(expected, result.Data); diff --git a/PoweredSoft.DynamicQuery.Test/SortTests.cs b/PoweredSoft.DynamicQuery.Test/SortTests.cs index 8d535ba..03f4e3b 100644 --- a/PoweredSoft.DynamicQuery.Test/SortTests.cs +++ b/PoweredSoft.DynamicQuery.Test/SortTests.cs @@ -27,7 +27,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Orders, criteria); Assert.Equal(shouldResult, result.Data); }); @@ -50,7 +50,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); var result = queryHandler.Execute(ctx.Orders, criteria); Assert.Equal(shouldResult, result.Data); }); @@ -83,7 +83,7 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandler(); + var queryHandler = new QueryHandler(Enumerable.Empty()); queryHandler.AddInterceptor(new MockSortInterceptor()); var result = queryHandler.Execute(ctx.Orders, criteria); Assert.Equal(shouldResult, result.Data); diff --git a/PoweredSoft.DynamicQuery/QueryHandler.cs b/PoweredSoft.DynamicQuery/QueryHandler.cs index 3aab5e1..83d1507 100644 --- a/PoweredSoft.DynamicQuery/QueryHandler.cs +++ b/PoweredSoft.DynamicQuery/QueryHandler.cs @@ -14,6 +14,10 @@ namespace PoweredSoft.DynamicQuery { public class QueryHandler : QueryHandlerBase, IQueryHandler { + public QueryHandler(IEnumerable queryableInterceptorProviders) : base(queryableInterceptorProviders) + { + } + protected virtual IQueryExecutionResult FinalExecute() { CommonBeforeExecute(); @@ -127,25 +131,25 @@ namespace PoweredSoft.DynamicQuery public IQueryExecutionResult Execute(IQueryable queryable, IQueryCriteria criteria) { - Reset(queryable, criteria, new QueryExecutionOptions()); + Reset(queryable, criteria, new QueryExecutionOptions()); return FinalExecute(); } public IQueryExecutionResult Execute(IQueryable queryable, IQueryCriteria criteria) { - Reset(queryable, criteria, new QueryExecutionOptions()); + Reset(queryable, criteria, new QueryExecutionOptions()); return FinalExecute(); } public IQueryExecutionResult Execute(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options) { - Reset(queryable, criteria, options); + Reset(queryable, criteria, options); return FinalExecute(); } public IQueryExecutionResult Execute(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options) { - Reset(queryable, criteria, options); + Reset(queryable, criteria, options); return FinalExecute(); } } diff --git a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs index 69c1a5f..9bb6784 100644 --- a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs +++ b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs @@ -15,7 +15,7 @@ namespace PoweredSoft.DynamicQuery { public IAsyncQueryableService AsyncQueryableService { get; } - public QueryHandlerAsync(IAsyncQueryableService asyncQueryableService) + public QueryHandlerAsync(IAsyncQueryableService asyncQueryableService, IEnumerable queryInterceptorProviders) : base(queryInterceptorProviders) { AsyncQueryableService = asyncQueryableService; } @@ -157,25 +157,25 @@ namespace PoweredSoft.DynamicQuery public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default) { - Reset(queryable, criteria, new QueryExecutionOptions()); + Reset(queryable, criteria, new QueryExecutionOptions()); return FinalExecuteAsync(cancellationToken); } public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, CancellationToken cancellationToken = default) { - Reset(queryable, criteria, new QueryExecutionOptions()); + Reset(queryable, criteria, new QueryExecutionOptions()); return FinalExecuteAsync(cancellationToken); } public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options, CancellationToken cancellationToken = default) { - Reset(queryable, criteria, options); + Reset(queryable, criteria, options); return FinalExecuteAsync(cancellationToken); } public Task> ExecuteAsync(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options, CancellationToken cancellationToken = default) { - Reset(queryable, criteria, options); + Reset(queryable, criteria, options); return FinalExecuteAsync(cancellationToken); } } diff --git a/PoweredSoft.DynamicQuery/QueryHandlerBase.cs b/PoweredSoft.DynamicQuery/QueryHandlerBase.cs index 4d5a271..ceab998 100644 --- a/PoweredSoft.DynamicQuery/QueryHandlerBase.cs +++ b/PoweredSoft.DynamicQuery/QueryHandlerBase.cs @@ -16,7 +16,9 @@ namespace PoweredSoft.DynamicQuery { public abstract class QueryHandlerBase : IInterceptableQueryHandler { - protected List Interceptors { get; } = new List(); + private readonly IEnumerable queryableInterceptorProviders; + + protected List AddedInterceptors { get; } = new List(); protected IQueryCriteria Criteria { get; set; } protected IQueryable QueryableAtStart { get; private set; } protected IQueryable CurrentQueryable { get; set; } @@ -26,8 +28,21 @@ namespace PoweredSoft.DynamicQuery protected bool HasGrouping => Criteria.Groups?.Any() == true; protected bool HasPaging => Criteria.PageSize.HasValue && Criteria.PageSize > 0; - protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options) + protected IReadOnlyList Interceptors { get; set; } + + protected virtual void ResetInterceptors(IQueryCriteria criteria, IQueryable queryable) { + Interceptors = ResolveInterceptors(criteria, queryable); + } + + public QueryHandlerBase(IEnumerable queryableInterceptorProviders) + { + this.queryableInterceptorProviders = queryableInterceptorProviders; + } + + protected virtual void Reset(IQueryable queryable, IQueryCriteria criteria, IQueryExecutionOptions options) + { + ResetInterceptors(criteria, queryable); Criteria = criteria ?? throw new ArgumentNullException("criteria"); QueryableAtStart = queryable ?? throw new ArgumentNullException("queryable"); CurrentQueryable = QueryableAtStart; @@ -54,8 +69,8 @@ namespace PoweredSoft.DynamicQuery { if (interceptor == null) throw new ArgumentNullException("interceptor"); - if (!Interceptors.Contains(interceptor)) - Interceptors.Add(interceptor); + if (!AddedInterceptors.Contains(interceptor)) + AddedInterceptors.Add(interceptor); } protected virtual IGroup InterceptGroup(IGroup group) @@ -473,5 +488,16 @@ namespace PoweredSoft.DynamicQuery await AfterReadInterceptors(pairs); } + + public IReadOnlyList ResolveInterceptors(IQueryCriteria criteria, IQueryable queryable) + { + var providedInterceptors = queryableInterceptorProviders.SelectMany(t => t.GetInterceptors(criteria, queryable)).ToList(); + var final = providedInterceptors + .Concat(AddedInterceptors) + .Distinct(new QueryInterceptorEqualityComparer()) + .ToList(); + + return final; + } } } diff --git a/PoweredSoft.DynamicQuery/QueryInterceptorEqualityComparer.cs b/PoweredSoft.DynamicQuery/QueryInterceptorEqualityComparer.cs new file mode 100644 index 0000000..e01ca81 --- /dev/null +++ b/PoweredSoft.DynamicQuery/QueryInterceptorEqualityComparer.cs @@ -0,0 +1,18 @@ +using PoweredSoft.DynamicQuery.Core; +using System.Collections.Generic; + +namespace PoweredSoft.DynamicQuery +{ + public class QueryInterceptorEqualityComparer : IEqualityComparer + { + public bool Equals(IQueryInterceptor x, IQueryInterceptor y) + { + return x.GetType() == y.GetType(); + } + + public int GetHashCode(IQueryInterceptor obj) + { + return obj.GetType().GetHashCode(); + } + } +}