LINQ:
var oldMans = Persons.Where(x => x.Sex == SexEnum.Masculine && x.Age > 60).ToList();
Specification:
var oldMans = Persons.Where(x => IsOldManSpecification(x)).ToList();
- The business logic is encapsuled in the specification (with a name that reveal what it is).
- DRY: you don't repeat that linq over the code, you just use the Specification
I like to use specification when I think that the rule is important enough to be explicit in the code and it doesn't belongs naturally to the entity.
Example:
public class Customer
{
//...
public bool IsAbleToReceiveCredit(decimal creditValue)
{
var secureAge = this.Age > 18 && this.Age < 60;
var personalAssetsGreaterThanCreditValue = this.PersonalAssets.Sum(x => x.Value) > creditValue;
return secureAge && personalAssetsGreaterThanCreditValue;
}
}
Is it from the Customer
the responsability to decide if he is able to receive some credit? A bank would ask to the customer if he can receive a loan?
Probably not.
So with specification you can remove that logic from the Customer
(it never belonged to it). You can create something like IsAbleToReceiveCreditSpecification
and put all logic there. We can go further and combine specifications, for example: you could create a SecureAgeSpecification
and a AssetsGreaterThanSpecification
and use them to compose the IsAbleToReceiveCreditSpecification
.
So I don't think LINQ replaces the Specification. In fact it improves the pattern. There are some implementations of Specification that use LINQ internally with IQueriable<T>
, with this you can use the specification inside your ORM queries on the Repository/DataAcess level.