Skip to content

Commit

Permalink
Added XML documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
fiseni committed Nov 8, 2024
1 parent b7b1bc0 commit ff58571
Show file tree
Hide file tree
Showing 55 changed files with 1,833 additions and 121 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>

<GenerateDocumentationFile>false</GenerateDocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Deterministic>true</Deterministic>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluator to apply AsNoTracking to the query if the specification has AsNoTracking set to true.
/// </summary>
public sealed class AsNoTrackingEvaluator : IEvaluator
{
private AsNoTrackingEvaluator() { }
/// <summary>
/// Gets the singleton instance of the <see cref="AsNoTrackingEvaluator"/> class.
/// </summary>
public static AsNoTrackingEvaluator Instance = new();
private AsNoTrackingEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
if (specification.AsNoTracking)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluator to apply AsNoTracking to the query if the specification has AsNoTracking set to true.
/// </summary>
public sealed class AsNoTrackingWithIdentityResolutionEvaluator : IEvaluator
{
private AsNoTrackingWithIdentityResolutionEvaluator() { }
/// <summary>
/// Gets the singleton instance of the <see cref="AsNoTrackingWithIdentityResolutionEvaluator"/> class.
/// </summary>
public static AsNoTrackingWithIdentityResolutionEvaluator Instance = new();
private AsNoTrackingWithIdentityResolutionEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
if (specification.AsNoTrackingWithIdentityResolution)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluator to apply AsSplitQuery to the query if the specification has AsSplitQuery set to true.
/// </summary>
public sealed class AsSplitQueryEvaluator : IEvaluator
{
private AsSplitQueryEvaluator() { }
/// <summary>
/// Gets the singleton instance of the <see cref="AsSplitQueryEvaluator"/> class.
/// </summary>
public static AsSplitQueryEvaluator Instance = new();
private AsSplitQueryEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
if (specification.AsSplitQuery)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluator to apply AsTracking to the query if the specification has AsTracking set to true.
/// </summary>
public sealed class AsTrackingEvaluator : IEvaluator
{
private AsTrackingEvaluator() { }
/// <summary>
/// Gets the singleton instance of the <see cref="AsTrackingEvaluator"/> class.
/// </summary>
public static AsTrackingEvaluator Instance = new();
private AsTrackingEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
if (specification.AsTracking)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluator to apply IgnoreQueryFilters to the query if the specification has IgnoreQueryFilters set to true.
/// </summary>
public sealed class IgnoreQueryFiltersEvaluator : IEvaluator
{
private IgnoreQueryFiltersEvaluator() { }

/// <summary>
/// Gets the singleton instance of the <see cref="IgnoreQueryFiltersEvaluator"/> class.
/// </summary>
public static IgnoreQueryFiltersEvaluator Instance = new();
private IgnoreQueryFiltersEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
if (specification.IgnoreQueryFilters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluates a specification to include navigation properties.
/// </summary>
public sealed class IncludeEvaluator : IEvaluator
{
private static readonly MethodInfo _includeMethodInfo = typeof(EntityFrameworkQueryableExtensions)
Expand Down Expand Up @@ -33,9 +36,14 @@ private static readonly MethodInfo _thenIncludeAfterEnumerableMethodInfo
private readonly record struct CacheKey(Type EntityType, Type PropertyType, Type? PreviousReturnType);
private static readonly ConcurrentDictionary<CacheKey, Func<IQueryable, LambdaExpression, IQueryable>> _cache = new();

private IncludeEvaluator() { }

/// <summary>
/// Gets the singleton instance of the <see cref="IncludeEvaluator"/> class.
/// </summary>
public static IncludeEvaluator Instance = new();
private IncludeEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
Type? previousReturnType = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluates a specification to include navigation properties specified by string paths.
/// </summary>
public sealed class IncludeStringEvaluator : IEvaluator
{
private IncludeStringEvaluator() { }

/// <summary>
/// Gets the singleton instance of the <see cref="IncludeStringEvaluator"/> class.
/// </summary>
public static IncludeStringEvaluator Instance = new();
private IncludeStringEvaluator() { }

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
foreach (var item in specification.Items)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ This was the previous implementation. We're trying to avoid allocations of LikeE
Instead of GroupBy, we have a single array, sorted by group, and we slice it to get the groups.
*/

/// <summary>
/// Evaluates a specification to apply "like" expressions for filtering.
/// </summary>
public sealed class LikeEvaluator : IEvaluator
{
private LikeEvaluator() { }

/// <summary>
/// Gets the singleton instance of the <see cref="LikeEvaluator"/> class.
/// </summary>
public static LikeEvaluator Instance = new();

/// <inheritdoc/>
public IQueryable<T> Evaluate<T>(IQueryable<T> source, Specification<T> specification) where T : class
{
var likeCount = GetLikeCount(specification);
Expand Down Expand Up @@ -103,4 +111,3 @@ private static void FillSorted<T>(Specification<T> specification, Span<SpecItem>
}
}
}

Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Evaluates specifications by applying a series of evaluators.
/// </summary>
public class SpecificationEvaluator
{
/// <summary>
/// Gets the default instance of the <see cref="SpecificationEvaluator"/> class.
/// </summary>
public static SpecificationEvaluator Default = new();

/// <summary>
/// Gets the list of evaluators.
/// </summary>
protected List<IEvaluator> Evaluators { get; }

/// <summary>
/// Initializes a new instance of the <see cref="SpecificationEvaluator"/> class.
/// </summary>
public SpecificationEvaluator()
{
Evaluators =
Expand All @@ -23,11 +35,24 @@ public SpecificationEvaluator()
];
}

/// <summary>
/// Initializes a new instance of the <see cref="SpecificationEvaluator"/> class with the specified evaluators.
/// </summary>
/// <param name="evaluators">The evaluators to use.</param>
public SpecificationEvaluator(IEnumerable<IEvaluator> evaluators)
{
Evaluators = evaluators.ToList();
}

/// <summary>
/// Evaluates the given specification on the provided queryable source and returns the result.
/// </summary>
/// <typeparam name="T">The type of the entity.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="specification">The specification to evaluate.</param>
/// <param name="ignorePaging">Whether to ignore paging settings (Take/Skip) defined in the specification.</param>
/// <returns>The evaluated queryable result.</returns>
public virtual IQueryable<TResult> Evaluate<T, TResult>(
IQueryable<T> source,
Specification<T, TResult> specification,
Expand All @@ -54,6 +79,14 @@ public virtual IQueryable<TResult> Evaluate<T, TResult>(
: resultQuery.ApplyPaging(specification);
}

/// <summary>
/// Evaluates the given specification on the provided queryable source and returns the result.
/// </summary>
/// <typeparam name="T">The type of the entity.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="specification">The specification to evaluate.</param>
/// <param name="ignorePaging">Whether to ignore paging settings (Take/Skip) defined in the specification.</param>
/// <returns>The evaluated queryable result.</returns>
public virtual IQueryable<T> Evaluate<T>(
IQueryable<T> source,
Specification<T> specification,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
namespace Pozitron.QuerySpecification;

/// <summary>
/// Provides extension methods for <see cref="IQueryable{T}"/> to apply specifications and pagination.
/// </summary>
public static class IQueryableExtensions
{
/// <summary>
/// Applies the given specification to the queryable source.
/// </summary>
/// <typeparam name="TSource">The type of the entity.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="specification">The specification to apply.</param>
/// <param name="evaluator">The specification evaluator to use. If null, the default evaluator is used.</param>
/// <returns>The queryable source with the specification applied.</returns>
public static IQueryable<TSource> WithSpecification<TSource>(
this IQueryable<TSource> source,
Specification<TSource> specification,
Expand All @@ -12,6 +23,15 @@ public static IQueryable<TSource> WithSpecification<TSource>(
return evaluator.Evaluate(source, specification);
}

/// <summary>
/// Applies the given specification to the queryable source and projects the result to a different type.
/// </summary>
/// <typeparam name="TSource">The type of the entity.</typeparam>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="specification">The specification to apply.</param>
/// <param name="evaluator">The specification evaluator to use. If null, the default evaluator is used.</param>
/// <returns>The queryable source with the specification applied and projected to the result type.</returns>
public static IQueryable<TResult> WithSpecification<TSource, TResult>(
this IQueryable<TSource> source,
Specification<TSource, TResult> specification,
Expand All @@ -22,13 +42,30 @@ public static IQueryable<TResult> WithSpecification<TSource, TResult>(
return evaluator.Evaluate(source, specification);
}

/// <summary>
/// Converts the queryable source to a paged result asynchronously.
/// </summary>
/// <typeparam name="TSource">The type of the entity.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="filter">The paging filter.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the paged result.</returns>
public static Task<PagedResult<TSource>> ToPagedResultAsync<TSource>(
this IQueryable<TSource> source,
PagingFilter filter,
CancellationToken cancellationToken = default)
where TSource : class
=> ToPagedResultAsync(source, filter, PaginationSettings.Default, cancellationToken);
=> ToPagedResultAsync(source, filter, PaginationSettings.Default, cancellationToken);

/// <summary>
/// Converts the queryable source to a paged result asynchronously with the specified pagination settings.
/// </summary>
/// <typeparam name="TSource">The type of the entity.</typeparam>
/// <param name="source">The queryable source.</param>
/// <param name="filter">The paging filter.</param>
/// <param name="paginationSettings">The pagination settings.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the paged result.</returns>
public static async Task<PagedResult<TSource>> ToPagedResultAsync<TSource>(
this IQueryable<TSource> source,
PagingFilter filter,
Expand Down
Loading

0 comments on commit ff58571

Please sign in to comment.