Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public SpecificationEvaluator(IEnumerable<IEvaluator> evaluators)
/// <inheritdoc/>
public virtual IQueryable<TResult> GetQuery<T, TResult>(IQueryable<T> query, ISpecification<T, TResult> specification) where T : class
{
if (specification is null) throw new ArgumentNullException(nameof(specification));
ArgumentNullException.ThrowIfNull(specification);
if (specification.Selector is null && specification.SelectorMany is null) throw new SelectorNotFoundException();
if (specification.Selector is not null && specification.SelectorMany is not null) throw new ConcurrentSelectorsException();

Expand All @@ -54,7 +54,7 @@ public virtual IQueryable<TResult> GetQuery<T, TResult>(IQueryable<T> query, ISp
/// <inheritdoc/>
public virtual IQueryable<T> GetQuery<T>(IQueryable<T> query, ISpecification<T> specification, bool evaluateCriteriaOnly = false) where T : class
{
if (specification is null) throw new ArgumentNullException(nameof(specification));
ArgumentNullException.ThrowIfNull(specification);

var evaluators = evaluateCriteriaOnly ? Evaluators.Where(x => x.IsCriteriaEvaluator) : Evaluators;

Expand Down
2 changes: 1 addition & 1 deletion src/Ardalis.Specification/Builders/SpecificationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal class SpecificationBuilder<T, TResult> : SpecificationBuilder<T>,
public new Specification<T, TResult> Specification { get; }

public SpecificationBuilder(Specification<T, TResult> specification)
:base(specification)
: base(specification)
{
Specification = specification;
}
Expand Down
34 changes: 15 additions & 19 deletions src/Ardalis.Specification/Specification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ public class Specification<T, TResult> : Specification<T>, ISpecification<T, TRe
/// <inheritdoc cref="ISpecification{T}"/>
public class Specification<T> : ISpecification<T>
{
private const int DEFAULT_CAPACITY_SEARCH = 2;

// It is utilized only during the building stage for the sub-chains. Once the state is built, we don't care about it anymore.
// The initial value is not important since the value is always initialized by the root of the chain.
// Therefore, we don't need ThreadLocal (it's more expensive).
Expand All @@ -43,8 +41,8 @@ public class Specification<T> : ISpecification<T>
private OneOrMany<OrderExpressionInfo<T>> _orderExpressions = new();
private OneOrMany<IncludeExpressionInfo> _includeExpressions = new();
private OneOrMany<string> _includeStrings = new();
private Dictionary<string, object>? _items;
private OneOrMany<string> _queryTags = new();
private Dictionary<string, object>? _items;

public ISpecificationBuilder<T> Query => new SpecificationBuilder<T>(this);
protected virtual IInMemorySpecificationEvaluator Evaluator => InMemorySpecificationEvaluator.Default;
Expand Down Expand Up @@ -88,15 +86,6 @@ public class Specification<T> : ISpecification<T>
/// <inheritdoc/>
public bool AsNoTrackingWithIdentityResolution { get; internal set; } = false;


// Specs are not intended to be thread-safe, so we don't need to worry about thread-safety here.
internal void Add(WhereExpressionInfo<T> whereExpression) => _whereExpressions.Add(whereExpression);
internal void Add(OrderExpressionInfo<T> orderExpression) => _orderExpressions.Add(orderExpression);
internal void Add(IncludeExpressionInfo includeExpression) => _includeExpressions.Add(includeExpression);
internal void Add(string includeString) => _includeStrings.Add(includeString);
internal void Add(SearchExpressionInfo<T> searchExpression) => _searchExpressions.AddSorted(searchExpression, SearchExpressionComparer<T>.Default);
internal void AddQueryTag(string queryTag) => _queryTags.Add(queryTag);

/// <inheritdoc/>
public Dictionary<string, object> Items => _items ??= [];

Expand All @@ -118,13 +107,6 @@ public class Specification<T> : ISpecification<T>
/// <inheritdoc/>
public IEnumerable<string> QueryTags => _queryTags.Values;

internal OneOrMany<WhereExpressionInfo<T>> OneOrManyWhereExpressions => _whereExpressions;
internal OneOrMany<SearchExpressionInfo<T>> OneOrManySearchExpressions => _searchExpressions;
internal OneOrMany<OrderExpressionInfo<T>> OneOrManyOrderExpressions => _orderExpressions;
internal OneOrMany<IncludeExpressionInfo> OneOrManyIncludeExpressions => _includeExpressions;
internal OneOrMany<string> OneOrManyIncludeStrings => _includeStrings;
internal OneOrMany<string> OneOrManyQueryTags => _queryTags;

/// <inheritdoc/>
public virtual IEnumerable<T> Evaluate(IEnumerable<T> entities)
{
Expand All @@ -139,6 +121,20 @@ public virtual bool IsSatisfiedBy(T entity)
return validator.IsValid(entity, this);
}

internal OneOrMany<WhereExpressionInfo<T>> OneOrManyWhereExpressions => _whereExpressions;
internal OneOrMany<SearchExpressionInfo<T>> OneOrManySearchExpressions => _searchExpressions;
internal OneOrMany<OrderExpressionInfo<T>> OneOrManyOrderExpressions => _orderExpressions;
internal OneOrMany<IncludeExpressionInfo> OneOrManyIncludeExpressions => _includeExpressions;
internal OneOrMany<string> OneOrManyIncludeStrings => _includeStrings;
internal OneOrMany<string> OneOrManyQueryTags => _queryTags;

internal void Add(WhereExpressionInfo<T> whereExpression) => _whereExpressions.Add(whereExpression);
internal void Add(SearchExpressionInfo<T> searchExpression) => _searchExpressions.AddSorted(searchExpression, SearchExpressionComparer<T>.Default);
internal void Add(OrderExpressionInfo<T> orderExpression) => _orderExpressions.Add(orderExpression);
internal void Add(IncludeExpressionInfo includeExpression) => _includeExpressions.Add(includeExpression);
internal void Add(string includeString) => _includeStrings.Add(includeString);
internal void AddQueryTag(string queryTag) => _queryTags.Add(queryTag);

internal Specification<T> Clone()
{
var newSpec = new Specification<T>();
Expand Down
6 changes: 3 additions & 3 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
</PropertyGroup>

<ItemGroup>
<None Include="../../icon.png" Pack="true" PackagePath="\" />
<None Include="../../readme-nuget.md" Pack="true" PackagePath="\" />
<None Include="../../LICENSE" Pack="true" PackagePath="\" />
<None Include="../../icon.png" Pack="true" PackagePath="\" Visible="false" />
<None Include="../../readme-nuget.md" Pack="true" PackagePath="\" Visible="false" />
<None Include="../../LICENSE" Pack="true" PackagePath="\" Visible="false" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ public void QueriesMatch_GivenMultipleSearchAsEnumerable()
[Fact]
public void QueriesMatch_GivenEmptyAsSpan()
{
var spec = new Specification<Store>();

var array = Array.Empty<SearchExpressionInfo<Store>>();

var actual = DbContext.Stores
Expand All @@ -71,8 +69,6 @@ public void QueriesMatch_GivenEmptyAsSpan()
[Fact]
public void QueriesMatch_GivenEmptyAsEnumerable()
{
var spec = new Specification<Store>();

var array = Array.Empty<SearchExpressionInfo<Store>>();

var actual = DbContext.Stores
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Tests.Fixture;
public class TestFactory : IAsyncLifetime
{
// Flag to force using Docker SQL Server. Update it manually if you want to avoid localDb locally.
private const bool _forceDocker = false;
private const bool FORCE_DOCKER = false;

private string _connectionString = default!;
private Respawner _respawner = default!;
Expand All @@ -21,7 +21,7 @@ public async Task InitializeAsync()
{
using (var localDB = new SqlLocalDbApi())
{
if (_forceDocker || !localDB.IsLocalDBInstalled())
if (FORCE_DOCKER || !localDB.IsLocalDBInstalled())
{
_dbContainer = CreateContainer();
await _dbContainer.StartAsync();
Expand Down