-
Notifications
You must be signed in to change notification settings - Fork 254
Description
We designed the infrastructure to be as extensible as possible. For example, users can define their own builder extensions, can define and inject their evaluators, validators and so on. But, all this is true as long you're working with the existing specification state. If you need to keep an additional information in the specification, then you have no other choice then define your own specification type (it may or may not inherit from the provided one in the library). This process can be tedious and it's not a simple task.
A common solution in these scenarios is just to define a IDictionary<string, object>
that can hold an arbitrary state. Users will be able to extend the state by adding it in the dictionary. Let's provide an example usage. Let's say we want to add support for "AsSingleQuery".
You define an extension to the builder:
namespace Ardalis.Specification;
public static class SpecificationExtensions
{
public static ISpecificationBuilder<T> AsSingleQuery<T>(
this ISpecificationBuilder<T> specificationBuilder,
bool condition = true) where T : class
{
if (condition)
{
specificationBuilder.Specification.Items["AsSingleQuery"] = true;
}
return specificationBuilder;
}
}
You define the evaluator:
using Microsoft.EntityFrameworkCore;
namespace Ardalis.Specification.EntityFrameworkCore;
public class AsSingleQueryEvaluator : IEvaluator
{
private AsSingleQueryEvaluator() { }
public static AsSingleQueryEvaluator Instance { get; } = new AsSingleQueryEvaluator();
public bool IsCriteriaEvaluator { get; } = true;
public IQueryable<T> GetQuery<T>(IQueryable<T> query, ISpecification<T> specification) where T : class
{
if (specification.Items.TryGetValue("AsSingleQuery", out var value) && (bool)value)
{
query = query.AsSingleQuery();
}
return query;
}
}
As seen above, this can greatly improve the extensibility of the specifications.