Skip to content

Commit ee131bc

Browse files
author
Bart Koelman
authored
Open up some members for extensibility. This helps to reduce some copy/pasted code in JsonApiDotNetCore.MongoDb. (#927)
1 parent b09e6b1 commit ee131bc

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryableBuilder.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace JsonApiDotNetCore.Queries.Internal.QueryableBuilding
1313
/// <summary>
1414
/// Drives conversion from <see cref="QueryLayer"/> into system <see cref="Expression"/> trees.
1515
/// </summary>
16-
public sealed class QueryableBuilder
16+
public class QueryableBuilder
1717
{
1818
private readonly Expression _source;
1919
private readonly Type _elementType;
@@ -38,7 +38,7 @@ public QueryableBuilder(Expression source, Type elementType, Type extensionType,
3838
_lambdaScopeFactory = lambdaScopeFactory ?? new LambdaScopeFactory(_nameFactory);
3939
}
4040

41-
public Expression ApplyQuery(QueryLayer layer)
41+
public virtual Expression ApplyQuery(QueryLayer layer)
4242
{
4343
if (layer == null) throw new ArgumentNullException(nameof(layer));
4444

@@ -72,39 +72,39 @@ public Expression ApplyQuery(QueryLayer layer)
7272
return expression;
7373
}
7474

75-
private Expression ApplyInclude(Expression source, IncludeExpression include, ResourceContext resourceContext)
75+
protected virtual Expression ApplyInclude(Expression source, IncludeExpression include, ResourceContext resourceContext)
7676
{
7777
using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);
7878

7979
var builder = new IncludeClauseBuilder(source, lambdaScope, resourceContext, _resourceContextProvider);
8080
return builder.ApplyInclude(include);
8181
}
8282

83-
private Expression ApplyFilter(Expression source, FilterExpression filter)
83+
protected virtual Expression ApplyFilter(Expression source, FilterExpression filter)
8484
{
8585
using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);
8686

8787
var builder = new WhereClauseBuilder(source, lambdaScope, _extensionType);
8888
return builder.ApplyWhere(filter);
8989
}
9090

91-
private Expression ApplySort(Expression source, SortExpression sort)
91+
protected virtual Expression ApplySort(Expression source, SortExpression sort)
9292
{
9393
using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);
9494

9595
var builder = new OrderClauseBuilder(source, lambdaScope, _extensionType);
9696
return builder.ApplyOrderBy(sort);
9797
}
9898

99-
private Expression ApplyPagination(Expression source, PaginationExpression pagination)
99+
protected virtual Expression ApplyPagination(Expression source, PaginationExpression pagination)
100100
{
101101
using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);
102102

103103
var builder = new SkipTakeClauseBuilder(source, lambdaScope, _extensionType);
104104
return builder.ApplySkipTake(pagination);
105105
}
106106

107-
private Expression ApplyProjection(Expression source, IDictionary<ResourceFieldAttribute, QueryLayer> projection, ResourceContext resourceContext)
107+
protected virtual Expression ApplyProjection(Expression source, IDictionary<ResourceFieldAttribute, QueryLayer> projection, ResourceContext resourceContext)
108108
{
109109
using var lambdaScope = _lambdaScopeFactory.CreateScope(_elementType);
110110

src/JsonApiDotNetCore/Repositories/ResourceRepositoryAccessor.cs

+13-13
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public ResourceRepositoryAccessor(IServiceProvider serviceProvider, IResourceCon
2626
public async Task<IReadOnlyCollection<TResource>> GetAsync<TResource>(QueryLayer layer, CancellationToken cancellationToken)
2727
where TResource : class, IIdentifiable
2828
{
29-
dynamic repository = GetReadRepository(typeof(TResource));
29+
dynamic repository = ResolveReadRepository(typeof(TResource));
3030
return (IReadOnlyCollection<TResource>) await repository.GetAsync(layer, cancellationToken);
3131
}
3232

@@ -35,83 +35,83 @@ public async Task<IReadOnlyCollection<IIdentifiable>> GetAsync(Type resourceType
3535
{
3636
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
3737

38-
dynamic repository = GetReadRepository(resourceType);
38+
dynamic repository = ResolveReadRepository(resourceType);
3939
return (IReadOnlyCollection<IIdentifiable>) await repository.GetAsync(layer, cancellationToken);
4040
}
4141

4242
/// <inheritdoc />
4343
public async Task<int> CountAsync<TResource>(FilterExpression topFilter, CancellationToken cancellationToken)
4444
where TResource : class, IIdentifiable
4545
{
46-
dynamic repository = GetReadRepository(typeof(TResource));
46+
dynamic repository = ResolveReadRepository(typeof(TResource));
4747
return (int) await repository.CountAsync(topFilter, cancellationToken);
4848
}
4949

5050
/// <inheritdoc />
5151
public async Task<TResource> GetForCreateAsync<TResource, TId>(TId id, CancellationToken cancellationToken)
5252
where TResource : class, IIdentifiable<TId>
5353
{
54-
dynamic repository = GetWriteRepository(typeof(TResource));
54+
dynamic repository = ResolveWriteRepository(typeof(TResource));
5555
return await repository.GetForCreateAsync(id, cancellationToken);
5656
}
5757

5858
/// <inheritdoc />
5959
public async Task CreateAsync<TResource>(TResource resourceFromRequest, TResource resourceForDatabase, CancellationToken cancellationToken)
6060
where TResource : class, IIdentifiable
6161
{
62-
dynamic repository = GetWriteRepository(typeof(TResource));
62+
dynamic repository = ResolveWriteRepository(typeof(TResource));
6363
await repository.CreateAsync(resourceFromRequest, resourceForDatabase, cancellationToken);
6464
}
6565

6666
/// <inheritdoc />
6767
public async Task<TResource> GetForUpdateAsync<TResource>(QueryLayer queryLayer, CancellationToken cancellationToken)
6868
where TResource : class, IIdentifiable
6969
{
70-
dynamic repository = GetWriteRepository(typeof(TResource));
70+
dynamic repository = ResolveWriteRepository(typeof(TResource));
7171
return await repository.GetForUpdateAsync(queryLayer, cancellationToken);
7272
}
7373

7474
/// <inheritdoc />
7575
public async Task UpdateAsync<TResource>(TResource resourceFromRequest, TResource resourceFromDatabase, CancellationToken cancellationToken)
7676
where TResource : class, IIdentifiable
7777
{
78-
dynamic repository = GetWriteRepository(typeof(TResource));
78+
dynamic repository = ResolveWriteRepository(typeof(TResource));
7979
await repository.UpdateAsync(resourceFromRequest, resourceFromDatabase, cancellationToken);
8080
}
8181

8282
/// <inheritdoc />
8383
public async Task DeleteAsync<TResource, TId>(TId id, CancellationToken cancellationToken)
8484
where TResource : class, IIdentifiable<TId>
8585
{
86-
dynamic repository = GetWriteRepository(typeof(TResource));
86+
dynamic repository = ResolveWriteRepository(typeof(TResource));
8787
await repository.DeleteAsync(id, cancellationToken);
8888
}
8989

9090
/// <inheritdoc />
9191
public async Task SetRelationshipAsync<TResource>(TResource primaryResource, object secondaryResourceIds, CancellationToken cancellationToken)
9292
where TResource : class, IIdentifiable
9393
{
94-
dynamic repository = GetWriteRepository(typeof(TResource));
94+
dynamic repository = ResolveWriteRepository(typeof(TResource));
9595
await repository.SetRelationshipAsync(primaryResource, secondaryResourceIds, cancellationToken);
9696
}
9797

9898
/// <inheritdoc />
9999
public async Task AddToToManyRelationshipAsync<TResource, TId>(TId primaryId, ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
100100
where TResource : class, IIdentifiable<TId>
101101
{
102-
dynamic repository = GetWriteRepository(typeof(TResource));
102+
dynamic repository = ResolveWriteRepository(typeof(TResource));
103103
await repository.AddToToManyRelationshipAsync(primaryId, secondaryResourceIds, cancellationToken);
104104
}
105105

106106
/// <inheritdoc />
107107
public async Task RemoveFromToManyRelationshipAsync<TResource>(TResource primaryResource, ISet<IIdentifiable> secondaryResourceIds, CancellationToken cancellationToken)
108108
where TResource : class, IIdentifiable
109109
{
110-
dynamic repository = GetWriteRepository(typeof(TResource));
110+
dynamic repository = ResolveWriteRepository(typeof(TResource));
111111
await repository.RemoveFromToManyRelationshipAsync(primaryResource, secondaryResourceIds, cancellationToken);
112112
}
113113

114-
protected object GetReadRepository(Type resourceType)
114+
protected virtual object ResolveReadRepository(Type resourceType)
115115
{
116116
var resourceContext = _resourceContextProvider.GetResourceContext(resourceType);
117117

@@ -130,7 +130,7 @@ protected object GetReadRepository(Type resourceType)
130130
return _serviceProvider.GetRequiredService(resourceDefinitionType);
131131
}
132132

133-
protected object GetWriteRepository(Type resourceType)
133+
protected virtual object ResolveWriteRepository(Type resourceType)
134134
{
135135
var resourceContext = _resourceContextProvider.GetResourceContext(resourceType);
136136

src/JsonApiDotNetCore/Resources/ResourceDefinitionAccessor.cs

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public IReadOnlyCollection<IncludeElementExpression> OnApplyIncludes(Type resour
2323
{
2424
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
2525

26-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
26+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
2727
return resourceDefinition.OnApplyIncludes(existingIncludes);
2828
}
2929

@@ -32,7 +32,7 @@ public FilterExpression OnApplyFilter(Type resourceType, FilterExpression existi
3232
{
3333
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
3434

35-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
35+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
3636
return resourceDefinition.OnApplyFilter(existingFilter);
3737
}
3838

@@ -41,7 +41,7 @@ public SortExpression OnApplySort(Type resourceType, SortExpression existingSort
4141
{
4242
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
4343

44-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
44+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
4545
return resourceDefinition.OnApplySort(existingSort);
4646
}
4747

@@ -50,7 +50,7 @@ public PaginationExpression OnApplyPagination(Type resourceType, PaginationExpre
5050
{
5151
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
5252

53-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
53+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
5454
return resourceDefinition.OnApplyPagination(existingPagination);
5555
}
5656

@@ -59,7 +59,7 @@ public SparseFieldSetExpression OnApplySparseFieldSet(Type resourceType, SparseF
5959
{
6060
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
6161

62-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
62+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
6363
return resourceDefinition.OnApplySparseFieldSet(existingSparseFieldSet);
6464
}
6565

@@ -69,7 +69,7 @@ public object GetQueryableHandlerForQueryStringParameter(Type resourceType, stri
6969
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
7070
if (parameterName == null) throw new ArgumentNullException(nameof(parameterName));
7171

72-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
72+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
7373
var handlers = resourceDefinition.OnRegisterQueryableHandlersForQueryStringParameters();
7474

7575
return handlers != null && handlers.ContainsKey(parameterName) ? handlers[parameterName] : null;
@@ -80,11 +80,11 @@ public IDictionary<string, object> GetMeta(Type resourceType, IIdentifiable reso
8080
{
8181
if (resourceType == null) throw new ArgumentNullException(nameof(resourceType));
8282

83-
dynamic resourceDefinition = GetResourceDefinition(resourceType);
83+
dynamic resourceDefinition = ResolveResourceDefinition(resourceType);
8484
return resourceDefinition.GetMeta((dynamic) resourceInstance);
8585
}
8686

87-
protected object GetResourceDefinition(Type resourceType)
87+
protected virtual object ResolveResourceDefinition(Type resourceType)
8888
{
8989
var resourceContext = _resourceContextProvider.GetResourceContext(resourceType);
9090

0 commit comments

Comments
 (0)