diff --git a/DynamicQuery.sln b/DynamicQuery.sln index f7c307e..dae0ac5 100644 --- a/DynamicQuery.sln +++ b/DynamicQuery.sln @@ -25,6 +25,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.Data.Core", ".. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.Data.EntityFrameworkCore", "..\Data\PoweredSoft.Data.EntityFrameworkCore\PoweredSoft.Data.EntityFrameworkCore.csproj", "{9D3ED339-8AF2-44B7-9AC5-720A0AC6C2FD}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.Data", "..\Data\PoweredSoft.Data\PoweredSoft.Data.csproj", "{1A039A0F-1D09-4CAC-B86F-5F16DC026375}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -63,6 +65,10 @@ Global {9D3ED339-8AF2-44B7-9AC5-720A0AC6C2FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D3ED339-8AF2-44B7-9AC5-720A0AC6C2FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D3ED339-8AF2-44B7-9AC5-720A0AC6C2FD}.Release|Any CPU.Build.0 = Release|Any CPU + {1A039A0F-1D09-4CAC-B86F-5F16DC026375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A039A0F-1D09-4CAC-B86F-5F16DC026375}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A039A0F-1D09-4CAC-B86F-5F16DC026375}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A039A0F-1D09-4CAC-B86F-5F16DC026375}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PoweredSoft.DynamicQuery.AspNetCore/MvcBuilderExtensions.cs b/PoweredSoft.DynamicQuery.AspNetCore/MvcBuilderExtensions.cs index cf00cc3..2308542 100644 --- a/PoweredSoft.DynamicQuery.AspNetCore/MvcBuilderExtensions.cs +++ b/PoweredSoft.DynamicQuery.AspNetCore/MvcBuilderExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json.Converters; +using PoweredSoft.Data; using PoweredSoft.DynamicQuery.AspNetCore.Json; using System; using System.Collections.Generic; @@ -11,6 +12,7 @@ namespace PoweredSoft.DynamicQuery.AspNetCore { public static IMvcBuilder AddPoweredSoftDynamicQuery(this IMvcBuilder builder) { + builder.Services.AddPoweredSoftDataServices(); builder.Services.AddPoweredSoftDynamicQuery(); var serviceProvider = builder.Services.BuildServiceProvider(); builder.AddJsonOptions(o => diff --git a/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj b/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj index ca0c52b..e654722 100644 --- a/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj +++ b/PoweredSoft.DynamicQuery.AspNetCore/PoweredSoft.DynamicQuery.AspNetCore.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs index 24ddcd0..26ad8b9 100644 --- a/PoweredSoft.DynamicQuery.Test/AsyncTests.cs +++ b/PoweredSoft.DynamicQuery.Test/AsyncTests.cs @@ -1,4 +1,5 @@ -using PoweredSoft.Data.EntityFrameworkCore; +using PoweredSoft.Data; +using PoweredSoft.Data.EntityFrameworkCore; using PoweredSoft.DynamicQuery.Core; using PoweredSoft.DynamicQuery.Test.Mock; using System; @@ -21,7 +22,7 @@ namespace PoweredSoft.DynamicQuery.Test var queryable = ctx.Items.AsQueryable(); // query handler that is empty should be the same as running to list. - var aqf = new AsyncQueryableFactory(); + var aqf = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); var criteria = new QueryCriteria(); var queryHandler = new QueryHandlerAsync(aqf); var result = await queryHandler.ExecuteAsync(queryable, criteria); @@ -61,8 +62,8 @@ namespace PoweredSoft.DynamicQuery.Test new Aggregate { Type = AggregateType.Avg, Path = "PriceAtTheTime"} } }; - - var queryHandler = new QueryHandlerAsync(new AsyncQueryableFactory()); + var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); + var queryHandler = new QueryHandlerAsync(asyncService); var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria); var groups = result.Data.Cast().ToList(); @@ -109,7 +110,8 @@ namespace PoweredSoft.DynamicQuery.Test } }; - var queryHandler = new QueryHandlerAsync(new AsyncQueryableFactory()); + var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); + var queryHandler = new QueryHandlerAsync(asyncService); var result = await queryHandler.ExecuteAsync(ctx.Items, criteria); Assert.Equal(resultShouldMatch, result.Data); }); @@ -128,7 +130,8 @@ namespace PoweredSoft.DynamicQuery.Test criteria.Page = 2; criteria.PageSize = 5; - var queryHandler = new QueryHandlerAsync(new AsyncQueryableFactory()); + var asyncService = new AsyncQueryableService(new[] { new AsyncQueryableHandlerService() }); + var queryHandler = new QueryHandlerAsync(asyncService); var result = await queryHandler.ExecuteAsync(ctx.OrderItems, criteria); Assert.Equal(resultShouldMatch, result.Data); }); diff --git a/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj b/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj index 9d23e38..22e6cc4 100644 --- a/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj +++ b/PoweredSoft.DynamicQuery/PoweredSoft.DynamicQuery.csproj @@ -22,6 +22,7 @@ + diff --git a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs index 9915e7c..ca32daf 100644 --- a/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs +++ b/PoweredSoft.DynamicQuery/QueryHandlerAsync.cs @@ -11,13 +11,15 @@ namespace PoweredSoft.DynamicQuery { public class QueryHandlerAsync : QueryHandlerBase, IQueryHandlerAsync { - public IAsyncQueryableFactory AsyncQueryableFactory { get; } internal MethodInfo ExecuteAsyncGeneric = typeof(QueryHandlerAsync).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).First(t => t.Name == "ExecuteAsync" && t.IsGenericMethod); + + public IAsyncQueryableService AsyncQueryableService { get; } + internal Task ExecuteAsyncReflected(CancellationToken cancellationToken) => (Task)ExecuteAsyncGeneric.MakeGenericMethod(QueryableUnderlyingType).Invoke(this, new object[] { cancellationToken }); - public QueryHandlerAsync(IAsyncQueryableFactory asyncQueryableFactory) + public QueryHandlerAsync(IAsyncQueryableService asyncQueryableService) { - AsyncQueryableFactory = asyncQueryableFactory; + AsyncQueryableService = asyncQueryableService; } protected virtual Task ExecuteAsync(CancellationToken cancellationToken = default(CancellationToken)) @@ -40,7 +42,7 @@ namespace PoweredSoft.DynamicQuery var queryableAfterFilters = CurrentQueryable; // async. - result.TotalRecords = await this.AsyncQueryableFactory.LongCountAsync((IQueryable)queryableAfterFilters, cancellationToken); + result.TotalRecords = await this.AsyncQueryableService.LongCountAsync((IQueryable)queryableAfterFilters, cancellationToken); CalculatePageCount(result); // intercept groups in advance to avoid doing it more than once :) @@ -65,7 +67,7 @@ namespace PoweredSoft.DynamicQuery }); // loop through the grouped records. - var groupRecords = await AsyncQueryableFactory.ToListAsync(CurrentQueryable.Cast(), cancellationToken); + var groupRecords = await AsyncQueryableService.ToListAsync(CurrentQueryable.Cast(), cancellationToken); // now join them into logical collections result.Data = RecursiveRegroup(groupRecords, aggregateResults, Criteria.Groups.First()); @@ -82,7 +84,7 @@ namespace PoweredSoft.DynamicQuery IQueryable afterFilterQueryable = (IQueryable)CurrentQueryable; // total records. - result.TotalRecords = await AsyncQueryableFactory.LongCountAsync(afterFilterQueryable, cancellationToken); + result.TotalRecords = await AsyncQueryableService.LongCountAsync(afterFilterQueryable, cancellationToken); CalculatePageCount(result); // sorts and paging. @@ -90,7 +92,7 @@ namespace PoweredSoft.DynamicQuery ApplyPaging(); // data. - var entities = await AsyncQueryableFactory.ToListAsync(((IQueryable)CurrentQueryable), cancellationToken); + var entities = await AsyncQueryableService.ToListAsync(((IQueryable)CurrentQueryable), cancellationToken); var records = InterceptConvertTo(entities); result.Data = records; @@ -105,7 +107,7 @@ namespace PoweredSoft.DynamicQuery return null; IQueryable selectExpression = CreateTotalAggregateSelectExpression(queryableAfterFilters); - var aggregateResult = await AsyncQueryableFactory.FirstOrDefaultAsync(selectExpression.Cast()); + var aggregateResult = await AsyncQueryableService.FirstOrDefaultAsync(selectExpression.Cast()); return MaterializeCalculateTotalAggregateResult(aggregateResult); } @@ -120,7 +122,7 @@ namespace PoweredSoft.DynamicQuery { IQueryable selectExpression = CreateFetchAggregateSelectExpression(fg, previousGroups); var selectExpressionCasted = selectExpression.Cast(); - var aggregateResult = AsyncQueryableFactory.ToListAsync(selectExpressionCasted, cancellationToken); + var aggregateResult = AsyncQueryableService.ToListAsync(selectExpressionCasted, cancellationToken); previousGroups.Add(fg); return aggregateResult; }));