diff --git a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs index ac64c6c15e..f71087c933 100644 --- a/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs +++ b/src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs @@ -13,7 +13,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding /// /// Drives conversion from into system trees. /// - public sealed class QueryableBuilder + public class QueryableBuilder { private readonly Expression _source; private readonly Type _elementType; @@ -38,7 +38,7 @@ public QueryableBuilder(Expression source, Type elementType, Type extensionType, _lambdaScopeFactory = lambdaScopeFactory ?? new LambdaScopeFactory(_nameFactory); } - public Expression ApplyQuery(QueryLayer layer) + public virtual Expression ApplyQuery(QueryLayer layer) { if (layer == null) throw new ArgumentNullException(nameof(layer)); @@ -72,7 +72,7 @@ public Expression ApplyQuery(QueryLayer layer) return expression; } - private Expression ApplyInclude(Expression source, IncludeExpression include, ResourceContext resourceContext) + protected virtual Expression ApplyInclude(Expression source, IncludeExpression include, ResourceContext resourceContext) { using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType); @@ -80,7 +80,7 @@ private Expression ApplyInclude(Expression source, IncludeExpression include, Re return builder.ApplyInclude(include); } - private Expression ApplyFilter(Expression source, FilterExpression filter) + protected virtual Expression ApplyFilter(Expression source, FilterExpression filter) { using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType); @@ -88,7 +88,7 @@ private Expression ApplyFilter(Expression source, FilterExpression filter) return builder.ApplyWhere(filter); } - private Expression ApplySort(Expression source, SortExpression sort) + protected virtual Expression ApplySort(Expression source, SortExpression sort) { using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType); @@ -96,7 +96,7 @@ private Expression ApplySort(Expression source, SortExpression sort) return builder.ApplyOrderBy(sort); } - private Expression ApplyPagination(Expression source, PaginationExpression pagination) + protected virtual Expression ApplyPagination(Expression source, PaginationExpression pagination) { using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType); @@ -104,7 +104,7 @@ private Expression ApplyPagination(Expression source, PaginationExpression pagin return builder.ApplySkipTake(pagination); } - private Expression ApplyProjection(Expression source, IDictionary projection, ResourceContext resourceContext) + protected virtual Expression ApplyProjection(Expression source, IDictionary projection, ResourceContext resourceContext) { using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType); diff --git a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs index 11aaaf2a05..61c64633a3 100644 --- a/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs +++ b/src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs @@ -26,7 +26,7 @@ public ResourceRepositoryAccessor(IServiceProvider serviceProvider, IResourceCon public async Task> GetAsync(QueryLayer layer, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetReadRepository(typeof(TResource)); + dynamic repository = ResolveReadRepository(typeof(TResource)); return (IReadOnlyCollection) await repository.GetAsync(layer, cancellationToken); } @@ -35,7 +35,7 @@ public async Task> GetAsync(Type resourceType { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic repository = GetReadRepository(resourceType); + dynamic repository = ResolveReadRepository(resourceType); return (IReadOnlyCollection) await repository.GetAsync(layer, cancellationToken); } @@ -43,7 +43,7 @@ public async Task> GetAsync(Type resourceType public async Task CountAsync(FilterExpression topFilter, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetReadRepository(typeof(TResource)); + dynamic repository = ResolveReadRepository(typeof(TResource)); return (int) await repository.CountAsync(topFilter, cancellationToken); } @@ -51,7 +51,7 @@ public async Task CountAsync(FilterExpression topFilter, Cancell public async Task GetForCreateAsync(TId id, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); return await repository.GetForCreateAsync(id, cancellationToken); } @@ -59,7 +59,7 @@ public async Task GetForCreateAsync(TId id, Cancellat public async Task CreateAsync(TResource resourceFromRequest, TResource resourceForDatabase, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.CreateAsync(resourceFromRequest, resourceForDatabase, cancellationToken); } @@ -67,7 +67,7 @@ public async Task CreateAsync(TResource resourceFromRequest, TResourc public async Task GetForUpdateAsync(QueryLayer queryLayer, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); return await repository.GetForUpdateAsync(queryLayer, cancellationToken); } @@ -75,7 +75,7 @@ public async Task GetForUpdateAsync(QueryLayer queryLayer, public async Task UpdateAsync(TResource resourceFromRequest, TResource resourceFromDatabase, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.UpdateAsync(resourceFromRequest, resourceFromDatabase, cancellationToken); } @@ -83,7 +83,7 @@ public async Task UpdateAsync(TResource resourceFromRequest, TResourc public async Task DeleteAsync(TId id, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.DeleteAsync(id, cancellationToken); } @@ -91,7 +91,7 @@ public async Task DeleteAsync(TId id, CancellationToken cancella public async Task SetRelationshipAsync(TResource primaryResource, object secondaryResourceIds, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.SetRelationshipAsync(primaryResource, secondaryResourceIds, cancellationToken); } @@ -99,7 +99,7 @@ public async Task SetRelationshipAsync(TResource primaryResource, obj public async Task AddToToManyRelationshipAsync(TId primaryId, ISet secondaryResourceIds, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.AddToToManyRelationshipAsync(primaryId, secondaryResourceIds, cancellationToken); } @@ -107,11 +107,11 @@ public async Task AddToToManyRelationshipAsync(TId primaryId, IS public async Task RemoveFromToManyRelationshipAsync(TResource primaryResource, ISet secondaryResourceIds, CancellationToken cancellationToken) where TResource : class, IIdentifiable { - dynamic repository = GetWriteRepository(typeof(TResource)); + dynamic repository = ResolveWriteRepository(typeof(TResource)); await repository.RemoveFromToManyRelationshipAsync(primaryResource, secondaryResourceIds, cancellationToken); } - protected object GetReadRepository(Type resourceType) + protected virtual object ResolveReadRepository(Type resourceType) { var resourceContext = _resourceContextProvider.GetResourceContext(resourceType); @@ -130,7 +130,7 @@ protected object GetReadRepository(Type resourceType) return _serviceProvider.GetRequiredService(resourceDefinitionType); } - protected object GetWriteRepository(Type resourceType) + protected virtual object ResolveWriteRepository(Type resourceType) { var resourceContext = _resourceContextProvider.GetResourceContext(resourceType); diff --git a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs index ed9b2ea1dd..44ed85ffe5 100644 --- a/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs +++ b/src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs @@ -23,7 +23,7 @@ public IReadOnlyCollection OnApplyIncludes(Type resour { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyIncludes(existingIncludes); } @@ -32,7 +32,7 @@ public FilterExpression OnApplyFilter(Type resourceType, FilterExpression existi { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyFilter(existingFilter); } @@ -41,7 +41,7 @@ public SortExpression OnApplySort(Type resourceType, SortExpression existingSort { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplySort(existingSort); } @@ -50,7 +50,7 @@ public PaginationExpression OnApplyPagination(Type resourceType, PaginationExpre { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplyPagination(existingPagination); } @@ -59,7 +59,7 @@ public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseF { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.OnApplySparseFieldSet(existingSparseFieldSet); } @@ -69,7 +69,7 @@ public object GetQueryableHandlerForQueryStringParameter(Type resourceType, stri if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); if (parameterName == null) throw new ArgumentNullException(nameof(parameterName)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); var handlers = resourceDefinition.OnRegisterQueryableHandlersForQueryStringParameters(); return handlers != null && handlers.ContainsKey(parameterName) ? handlers[parameterName] : null; @@ -80,11 +80,11 @@ public IDictionary GetMeta(Type resourceType, IIdentifiable reso { if (resourceType == null) throw new ArgumentNullException(nameof(resourceType)); - dynamic resourceDefinition = GetResourceDefinition(resourceType); + dynamic resourceDefinition = ResolveResourceDefinition(resourceType); return resourceDefinition.GetMeta((dynamic) resourceInstance); } - protected object GetResourceDefinition(Type resourceType) + protected virtual object ResolveResourceDefinition(Type resourceType) { var resourceContext = _resourceContextProvider.GetResourceContext(resourceType);