Flowsy.Specification
0.1.0
See the version list below for details.
dotnet add package Flowsy.Specification --version 0.1.0
NuGet\Install-Package Flowsy.Specification -Version 0.1.0
<PackageReference Include="Flowsy.Specification" Version="0.1.0" />
paket add Flowsy.Specification --version 0.1.0
#r "nuget: Flowsy.Specification, 0.1.0"
// Install Flowsy.Specification as a Cake Addin #addin nuget:?package=Flowsy.Specification&version=0.1.0 // Install Flowsy.Specification as a Cake Tool #tool nuget:?package=Flowsy.Specification&version=0.1.0
Flowsy Specification
Concepts
The Specification Pattern is a design pattern used to encapsulate business rules or conditions and make them reusable and composable.
ISpecification Interface
public interface ISpecification<TCandidate>
{
bool IsSatisfiedBy(TCandidate? candidate);
SpecificationEvaluation<TCandidate> Evaluate(TCandidate? candidate);
ISpecification<TCandidate> And(ISpecification<TCandidate> other);
ISpecification<TCandidate> Or(ISpecification<TCandidate> other);
ISpecification<TCandidate> Not();
}
Although you can implement this interface directly, the AbstractSpecification class provides reusable functionality to simplify the process of creating your own specifications.
Example
In the following example, the Customer entity holds information about a customer's credit limit and their outstanding balance:
public class Customer
{
public string Name { get; set; } = string.Empty;
public decimal CreditLimit { get; set; }
public decimal OutstandingBalance { get; set; }
}
Using specifications we can create reusable objects that tell us if our business rules are satisfied.
public class CreditApprovalSpecification : AbstractSpecification<Customer>
{
public override bool IsSatisfiedBy(Customer? candidate)
{
if (candidate is null)
return false;
return candidate.OutstandingBalance <= candidate.CreditLimit;
}
public override SpecificationEvaluation<Customer> Evaluate(Customer? candidate)
{
var isSatisfied = IsSatisfiedBy(candidate);
var explanation = isSatisfied
? "Credit approval granted. Customer is eligible for additional credit."
: $"Credit approval denied. Exceeded credit limit ({candidate?.CreditLimit}). Outstanding balance: {candidate?.OutstandingBalance}.";
return new SpecificationEvaluation<Customer>(this, candidate, isSatisfied, explanation);
}
}
And now we can reuse our business rules:
public class Program
{
public static void Main()
{
var customers = new List<Customer>();
// Populate customer list
var creditApproval = new CreditApprovalSpecification();
foreach (var customer in customers)
{
var evaluation = creditApproval.Evaluate(customer);
Console.WriteLine(
@"Credit approved for customer {0}? {1} ({2})",
customer.Name,
evaluation.IsSatisfied ? "Yes" : "No",
evaluation.Explanation
);
}
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.1 is compatible. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.