Raffinert.Spec
1.7.3
dotnet add package Raffinert.Spec --version 1.7.3
NuGet\Install-Package Raffinert.Spec -Version 1.7.3
<PackageReference Include="Raffinert.Spec" Version="1.7.3" />
<PackageVersion Include="Raffinert.Spec" Version="1.7.3" />
<PackageReference Include="Raffinert.Spec" />
paket add Raffinert.Spec --version 1.7.3
#r "nuget: Raffinert.Spec, 1.7.3"
#:package Raffinert.Spec@1.7.3
#addin nuget:?package=Raffinert.Spec&version=1.7.3
#tool nuget:?package=Raffinert.Spec&version=1.7.3
Raffinert.Spec
Raffinert.Spec
Raffinert.Spec
is a rethinking of libraries and sources such as:
Why Another Specification Library?
The main goal was to create a simple replacement of LINQKit library without any Entity Framework specific tweaks (see the LINQKit vs Spec Comparison and discussion about embedding linqKit into EfCore). Please treat the specification as an expression constructor.
With Raffinert.Spec you can:
- Combine expressions with logical operators OR, AND, NOT.
- Use nested specifications by calling
IsSatisfiedBy
method. - Create specification templates and apply them to different entities with similar signatures.
Usage
Detailed examples can be found in Integration Tests
Defining a Specification
You can define specifications either inline or create custom specification classes. Below is an example of a custom specification for filtering products by name:
using Raffinert.Spec;
using System.Linq.Expressions;
public class ProductNameSpec : Spec<Product>
{
private readonly string _name;
public ProductNameSpec(string name)
{
_name = name;
}
public override Expression<Func<Product, bool>> GetExpression()
{
return product => product.Name == _name;
}
}
Specification Templates
Specification templates allow you to define reusable structures that can be adapted to different entities with similar properties.
Example: Creating and Adapting a Specification Template
var template = SpecTemplate<Product>.Create(p => new { p.Name, p.Price }, t => t.Name == "Banana" && t.Price > 10);
var adaptedSpec = template.Adapt<InventoryItem>();
In this example, a specification template is created for Product
, filtering based on Name
and Price
. The template is then adapted to an InventoryItem
type with matching properties.
Roslyn Analyzers for Compile-Time Validation
To prevent runtime errors when using SpecTemplate
, we provide Roslyn Raffinert.Spec.Analyzer that:
- Ensure
SpecTemplate<TSample>.Adapt<TN>()
only adapts to types that contain all required members. - Validate that
SpecTemplate.Create(...)
uses either an anonymous type projection (e.g.,p => new { p.Name }
) or class initialize statement (e.g.,p => new Template{ Name = p.Name }
).
These analyzers catch issues at compile-time, improving reliability and maintainability.
Debugging
The Spec<T>
class includes built-in debugging support with a custom debugger display, giving developers an immediate view of the underlying expression while debugging.
See also Raffinert.Proj library.
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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. 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.0
- 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.