Class SpecBase<TModel, TMetadata>
- Namespace
- Motiv
- Assembly
- Motiv.dll
The base class for all specifications. A specification is an encapsulated predicate that can be evaluated against a model. When the predicate is evaluated, it returns a result that contains the Boolean result of the predicate as well as metadata that captures the meaning behind the predicate. By encapsulating the predicate, we can supply methods to assist with combining specifications together to form more complex specifications.
public abstract class SpecBase<TModel, TMetadata> : SpecBase<TModel>
Type Parameters
TModelThe model type that the specification will evaluate against
TMetadataThe type of the metadata to associate with the predicate
- Inheritance
-
SpecBase<TModel>SpecBase<TModel, TMetadata>
- Derived
- Inherited Members
- Extension Methods
Methods
And(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical AND operator. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). Both operands are evaluated sequentially (left, then right), regardless of the left operand's outcome.
public AsyncSpecBase<TModel, TMetadata> And(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical AND of this specification and the other specification.
And(SpecBase<TModel, TMetadata>)
Combines this specification with another specification using the logical AND operator. Both operands will be
evaluated, regardless of whether the left operand evaluated to false
public SpecBase<TModel, TMetadata> And(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The specification to combine with this specification.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical AND of this specification and the other specification.
AndAlso(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the conditional AND operator. This
specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). The right
operand is only evaluated if the left operand resolves to true — for asynchronous specifications
this means the right operand's work (including any I/O) is never started.
public AsyncSpecBase<TModel, TMetadata> AndAlso(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the conditional AND of this specification and the other specification.
AndAlso(SpecBase<TModel, TMetadata>)
Combines this specification with another specification using the conditional AND operator. The right operand
is only evaluated if the left operand resolves to true, since a false left operand means the
AND operation cannot return true. This is commonly referred to as "short-circuiting".
public SpecBase<TModel, TMetadata> AndAlso(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The specification to combine with this specification.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the conditional AND of this specification and the other specification.
AndConcurrently(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical AND operator, evaluating both operands concurrently. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). The result is indistinguishable from And(AsyncSpecBase<TModel, TMetadata>) — the reason, assertions, and justification are identical; only the evaluation strategy differs. Only use this when both operands' predicates are safe to execute concurrently (e.g. they do not share a non-thread-safe dependency such as an EF Core DbContext).
public AsyncSpecBase<TModel, TMetadata> AndConcurrently(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical AND of this specification and the other specification.
ChangeModelTo<TDerivedModel>()
Changes the TModel Type of the specification.
public SpecBase<TDerivedModel, TMetadata> ChangeModelTo<TDerivedModel>() where TDerivedModel : TModel
Returns
- SpecBase<TDerivedModel, TMetadata>
A new specification that represents the same specification but with a different
TModel.
Type Parameters
TDerivedModelThe type to change the
TModelto. This type must be a subclass ofTModel.
ChangeModelTo<TNewModel>(Func<TNewModel, TModel>)
Changes the TModel Type of the specification.
public SpecBase<TNewModel, TMetadata> ChangeModelTo<TNewModel>(Func<TNewModel, TModel> childModelSelector)
Parameters
childModelSelectorFunc<TNewModel, TModel>A function that takes the model and returns the child model to evaluate the specification against.
Returns
- SpecBase<TNewModel, TMetadata>
A new specification that represents the same specification but with a different
TModel.
Type Parameters
TNewModel
Evaluate(TModel)
Evaluates the proposition against the model and returns a result that contains the Boolean result of the predicate in addition to the metadata.
public BooleanResultBase<TMetadata> Evaluate(TModel model)
Parameters
modelTModelThe model to evaluate the specification against.
Returns
- BooleanResultBase<TMetadata>
A result that contains the Boolean result of the predicate in addition to the metadata.
EvaluateSpec(TModel)
Evaluates the specification against the model and returns a result that contains the Boolean result of the predicate in addition to the metadata.
protected abstract BooleanResultBase<TMetadata> EvaluateSpec(TModel model)
Parameters
modelTModelThe model to evaluate the specification against.
Returns
- BooleanResultBase<TMetadata>
A result that contains the Boolean result of the predicate in addition to the metadata.
IsSatisfiedBy(TModel)
Evaluates the proposition against the model and returns a result that contains the Boolean result of the predicate in addition to the metadata.
[Obsolete("Use Evaluate instead.")]
public BooleanResultBase<TMetadata> IsSatisfiedBy(TModel model)
Parameters
modelTModelThe model to evaluate the specification against.
Returns
- BooleanResultBase<TMetadata>
A result that contains the Boolean result of the predicate in addition to the metadata.
Matches(TModel)
Evaluates the proposition against the model and returns a boolean indicating whether it is satisfied, without allocating result objects.
public override bool Matches(TModel model)
Parameters
modelTModelThe model to evaluate the specification against.
Returns
- bool
trueif the model satisfies the proposition; otherwise,false.
Not()
Negates this specification.
public SpecBase<TModel, TMetadata> Not()
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical NOT of this specification.
Or(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical OR operator. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec().
public AsyncSpecBase<TModel, TMetadata> Or(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical OR of this specification and the other specification.
Or(SpecBase<TModel, TMetadata>)
Combines this specification with another specification using the logical OR operator.
public SpecBase<TModel, TMetadata> Or(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The specification to combine with this specification.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical OR of this specification and the other specification.
OrConcurrently(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical OR operator, evaluating both operands concurrently. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). The result is indistinguishable from Or(AsyncSpecBase<TModel, TMetadata>) — the reason, assertions, and justification are identical; only the evaluation strategy differs. Only use this when both operands' predicates are safe to execute concurrently (e.g. they do not share a non-thread-safe dependency such as an EF Core DbContext).
public AsyncSpecBase<TModel, TMetadata> OrConcurrently(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical OR of this specification and the other specification.
OrElse(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the conditional OR operator. This
specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). The right
operand is only evaluated if the left operand resolves to false, since a true left
operand means the OR operation is already satisfied — for asynchronous specifications this means the
right operand's work (including any I/O) is never started.
public AsyncSpecBase<TModel, TMetadata> OrElse(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous right operand.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the conditional OR of this specification and the other specification.
OrElse(SpecBase<TModel, TMetadata>)
Combines this specification with another specification using the conditional OR operator. The right operand
is only evaluated if the left operand resolves to false, since a true left operand means the
OR operation is already satisfied. This is commonly referred to as "short-circuiting".
public SpecBase<TModel, TMetadata> OrElse(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The right operand.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the conditional OR of this specification and the other specification.
ToAsyncSpec()
Lifts this synchronous specification into the asynchronous specification hierarchy so that it can be composed with asynchronous specifications. Evaluation remains fully synchronous internally; results are identical to those produced by Evaluate(TModel).
public AsyncSpecBase<TModel, TMetadata> ToAsyncSpec()
Returns
- AsyncSpecBase<TModel, TMetadata>
An asynchronous view over this specification.
ToExplanationSpec()
Converts this specification to an explanation specification (i.e., Spec<TModel, string>). This is necessary when establishing a "lowest-common-denominator" between very different specification. Therefore, specifications with different metadata types will be wrapped in a spec that uses string as the metadata type.
public override SpecBase<TModel, string> ToExplanationSpec()
Returns
ToString()
Serializes the logical hierarchy of the specification to a string.
public override string ToString()
Returns
- string
A string that represents the logical hierarchy of the specification.
XOr(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical XOR operator. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). Both operands are evaluated sequentially (left, then right), regardless of the outcome.
public AsyncSpecBase<TModel, TMetadata> XOr(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical XOR of this specification and the other specification.
XOr(SpecBase<TModel, TMetadata>)
Combines this specification with another specification using the logical XOR operator.
public SpecBase<TModel, TMetadata> XOr(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The specification to combine with this specification.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical XOR of this specification and the other specification.
XOrConcurrently(AsyncSpecBase<TModel, TMetadata>)
Combines this specification with an asynchronous specification using the logical XOR operator, evaluating both operands concurrently. This specification is lifted into the asynchronous hierarchy via ToAsyncSpec(). The result is indistinguishable from XOr(AsyncSpecBase<TModel, TMetadata>) — the reason, assertions, and justification are identical; only the evaluation strategy differs. Only use this when both operands' predicates are safe to execute concurrently (e.g. they do not share a non-thread-safe dependency such as an EF Core DbContext).
public AsyncSpecBase<TModel, TMetadata> XOrConcurrently(AsyncSpecBase<TModel, TMetadata> spec)
Parameters
specAsyncSpecBase<TModel, TMetadata>The asynchronous specification to combine with this specification.
Returns
- AsyncSpecBase<TModel, TMetadata>
A new specification that represents the logical XOR of this specification and the other specification.
Operators
operator &(SpecBase<TModel, TMetadata>, SpecBase<TModel, TMetadata>)
Combines two specifications using the logical AND operator.
public static SpecBase<TModel, TMetadata> operator &(SpecBase<TModel, TMetadata> left, SpecBase<TModel, TMetadata> right)
Parameters
leftSpecBase<TModel, TMetadata>The left operand of the AND operation.
rightSpecBase<TModel, TMetadata>The right operand of the AND operation.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical AND of the two specifications.
operator |(SpecBase<TModel, TMetadata>, SpecBase<TModel, TMetadata>)
Combines two specifications using the logical OR operator.
public static SpecBase<TModel, TMetadata> operator |(SpecBase<TModel, TMetadata> left, SpecBase<TModel, TMetadata> right)
Parameters
leftSpecBase<TModel, TMetadata>The left operand of the OR operation.
rightSpecBase<TModel, TMetadata>The right operand of the OR operation.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical OR of the two specifications.
operator ^(SpecBase<TModel, TMetadata>, SpecBase<TModel, TMetadata>)
Combines two specifications using the logical XOR operator.
public static SpecBase<TModel, TMetadata> operator ^(SpecBase<TModel, TMetadata> left, SpecBase<TModel, TMetadata> right)
Parameters
leftSpecBase<TModel, TMetadata>The left operand of the XOR operation.
rightSpecBase<TModel, TMetadata>The right operand of the XOR operation.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical XOR of the two specifications.
operator !(SpecBase<TModel, TMetadata>)
Negates a specification.
public static SpecBase<TModel, TMetadata> operator !(SpecBase<TModel, TMetadata> spec)
Parameters
specSpecBase<TModel, TMetadata>The specification to negate.
Returns
- SpecBase<TModel, TMetadata>
A new specification that represents the logical NOT of the specification.